security/nss/coreconf/mkdepend/include.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 /* $Xorg: include.c,v 1.4 2001/02/09 02:03:16 xorgcvs Exp $ */
     2 /*
     4 Copyright (c) 1993, 1994, 1998 The Open Group
     6 Permission to use, copy, modify, distribute, and sell this software and its
     7 documentation for any purpose is hereby granted without fee, provided that
     8 the above copyright notice appear in all copies and that both that
     9 copyright notice and this permission notice appear in supporting
    10 documentation.
    12 The above copyright notice and this permission notice shall be included in
    13 all copies or substantial portions of the Software.
    15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
    18 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
    19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
    20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
    22 Except as contained in this notice, the name of The Open Group shall not be
    23 used in advertising or otherwise to promote the sale, use or other dealings
    24 in this Software without prior written authorization from The Open Group.
    26 */
    27 /* $XFree86: xc/config/makedepend/include.c,v 3.7 2001/12/14 19:53:20 dawes Exp $ */
    30 #include "def.h"
    32 #ifdef _MSC_VER
    33 #include <windows.h>
    34 static int
    35 does_file_exist(char *file)
    36 {
    37   WIN32_FILE_ATTRIBUTE_DATA data;
    38   BOOL b = GetFileAttributesExA(file, GetFileExInfoStandard, &data);
    39   if (!b)
    40     return 0;
    41   return (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0;
    42 }
    43 #else
    44 static int
    45 does_file_exist(char *file)
    46 {
    47   struct stat sb;
    48   return stat(file, &sb) == 0 && !S_ISDIR(sb.st_mode);
    49 }
    50 #endif
    52 extern struct	inclist	inclist[ MAXFILES ],
    53 			*inclistp, *inclistnext;
    54 extern char	*includedirs[ ],
    55 		**includedirsnext;
    56 extern char	*notdotdot[ ];
    57 extern boolean show_where_not;
    58 extern boolean warn_multiple;
    60 static boolean
    61 isdot(char *p)
    62 {
    63 	if(p && *p++ == '.' && *p++ == '\0')
    64 		return(TRUE);
    65 	return(FALSE);
    66 }
    68 static boolean
    69 isdotdot(char *p)
    70 {
    71 	if(p && *p++ == '.' && *p++ == '.' && *p++ == '\0')
    72 		return(TRUE);
    73 	return(FALSE);
    74 }
    76 static boolean
    77 issymbolic(char *dir, char *component)
    78 {
    79 #ifdef S_IFLNK
    80 	struct stat	st;
    81 	char	buf[ BUFSIZ ], **pp;
    83 	sprintf(buf, "%s%s%s", dir, *dir ? "/" : "", component);
    84 	for (pp=notdotdot; *pp; pp++)
    85 		if (strcmp(*pp, buf) == 0)
    86 			return (TRUE);
    87 	if (lstat(buf, &st) == 0
    88 	&& (st.st_mode & S_IFMT) == S_IFLNK) {
    89 		*pp++ = copy(buf);
    90 		if (pp >= &notdotdot[ MAXDIRS ])
    91 			fatalerr("out of .. dirs, increase MAXDIRS\n");
    92 		return(TRUE);
    93 	}
    94 #endif
    95 	return(FALSE);
    96 }
    98 /*
    99  * Occasionally, pathnames are created that look like .../x/../y
   100  * Any of the 'x/..' sequences within the name can be eliminated.
   101  * (but only if 'x' is not a symbolic link!!)
   102  */
   103 static void
   104 remove_dotdot(char *path)
   105 {
   106 	register char	*end, *from, *to, **cp;
   107 	char		*components[ MAXFILES ],
   108 			newpath[ BUFSIZ ];
   109 	boolean		component_copied;
   111 	/*
   112 	 * slice path up into components.
   113 	 */
   114 	to = newpath;
   115 	if (*path == '/')
   116 		*to++ = '/';
   117 	*to = '\0';
   118 	cp = components;
   119 	for (from=end=path; *end; end++)
   120 		if (*end == '/') {
   121 			while (*end == '/')
   122 				*end++ = '\0';
   123 			if (*from)
   124 				*cp++ = from;
   125 			from = end;
   126 		}
   127 	*cp++ = from;
   128 	*cp = NULL;
   130 	/*
   131 	 * Recursively remove all 'x/..' component pairs.
   132 	 */
   133 	cp = components;
   134 	while(*cp) {
   135 		if (!isdot(*cp) && !isdotdot(*cp) && isdotdot(*(cp+1))
   136 		    && !issymbolic(newpath, *cp))
   137 		{
   138 		    char **fp = cp + 2;
   139 		    char **tp = cp;
   141 		    do 
   142 			*tp++ = *fp; /* move all the pointers down */
   143 		    while (*fp++);
   144 		    if (cp != components)
   145 			cp--;	/* go back and check for nested ".." */
   146 		} else {
   147 		    cp++;
   148 		}
   149 	}
   150 	/*
   151 	 * Concatenate the remaining path elements.
   152 	 */
   153 	cp = components;
   154 	component_copied = FALSE;
   155 	while(*cp) {
   156 		if (component_copied)
   157 			*to++ = '/';
   158 		component_copied = TRUE;
   159 		for (from = *cp; *from; )
   160 			*to++ = *from++;
   161 		*to = '\0';
   162 		cp++;
   163 	}
   164 	*to++ = '\0';
   166 	/*
   167 	 * copy the reconstituted path back to our pointer.
   168 	 */
   169 	strcpy(path, newpath);
   170 }
   172 /*
   173  * Add an include file to the list of those included by 'file'.
   174  */
   175 struct inclist *
   176 newinclude(char *newfile, char *incstring)
   177 {
   178 	register struct inclist	*ip;
   180 	/*
   181 	 * First, put this file on the global list of include files.
   182 	 */
   183 	ip = inclistp++;
   184 	if (inclistp == inclist + MAXFILES - 1)
   185 		fatalerr("out of space: increase MAXFILES\n");
   186 	ip->i_file = copy(newfile);
   188 	if (incstring == NULL)
   189 		ip->i_incstring = ip->i_file;
   190 	else
   191 		ip->i_incstring = copy(incstring);
   193 	inclistnext = inclistp;
   194 	return(ip);
   195 }
   197 void
   198 included_by(struct inclist *ip, struct inclist *newfile)
   199 {
   200 	register int i;
   202 	if (ip == NULL)
   203 		return;
   204 	/*
   205 	 * Put this include file (newfile) on the list of files included
   206 	 * by 'file'.  If 'file' is NULL, then it is not an include
   207 	 * file itself (i.e. was probably mentioned on the command line).
   208 	 * If it is already on the list, don't stick it on again.
   209 	 */
   210 	if (ip->i_list == NULL) {
   211 		ip->i_list = (struct inclist **)
   212 			malloc(sizeof(struct inclist *) * ++ip->i_listlen);
   213 		ip->i_merged = (boolean *)
   214 		    malloc(sizeof(boolean) * ip->i_listlen);
   215 	} else {
   216 		for (i=0; i<ip->i_listlen; i++)
   217 			if (ip->i_list[ i ] == newfile) {
   218 			    i = strlen(newfile->i_file);
   219 			    if (!(ip->i_flags & INCLUDED_SYM) &&
   220 				!(i > 2 &&
   221 				  newfile->i_file[i-1] == 'c' &&
   222 				  newfile->i_file[i-2] == '.'))
   223 			    {
   224 				/* only bitch if ip has */
   225 				/* no #include SYMBOL lines  */
   226 				/* and is not a .c file */
   227 				if (warn_multiple)
   228 				{
   229 					warning("%s includes %s more than once!\n",
   230 						ip->i_file, newfile->i_file);
   231 					warning1("Already have\n");
   232 					for (i=0; i<ip->i_listlen; i++)
   233 						warning1("\t%s\n", ip->i_list[i]->i_file);
   234 				}
   235 			    }
   236 			    return;
   237 			}
   238 		ip->i_list = (struct inclist **) realloc(ip->i_list,
   239 			sizeof(struct inclist *) * ++ip->i_listlen);
   240 		ip->i_merged = (boolean *)
   241 		    realloc(ip->i_merged, sizeof(boolean) * ip->i_listlen);
   242 	}
   243 	ip->i_list[ ip->i_listlen-1 ] = newfile;
   244 	ip->i_merged[ ip->i_listlen-1 ] = FALSE;
   245 }
   247 void
   248 inc_clean (void)
   249 {
   250 	register struct inclist *ip;
   252 	for (ip = inclist; ip < inclistp; ip++) {
   253 		ip->i_flags &= ~MARKED;
   254 	}
   255 }
   257 struct inclist *
   258 inc_path(char *file, char *include, int type)
   259 {
   260 	static char		path[ BUFSIZ ];
   261 	register char		**pp, *p;
   262 	register struct inclist	*ip;
   264 	/*
   265 	 * Check all previously found include files for a path that
   266 	 * has already been expanded.
   267 	 */
   268 	if ((type == INCLUDE) || (type == INCLUDEDOT))
   269 		inclistnext = inclist;
   270 	ip = inclistnext;
   272 	for (; ip->i_file; ip++) {
   273 		if ((strcmp(ip->i_incstring, include) == 0) &&
   274 		    !(ip->i_flags & INCLUDED_SYM)) {
   275 			inclistnext = ip + 1;
   276 			return ip;
   277 		}
   278 	}
   280 	if (inclistnext == inclist) {
   281 		/*
   282 		 * If the path was surrounded by "" or is an absolute path,
   283 		 * then check the exact path provided.
   284 		 */
   285 		if ((type == INCLUDEDOT) ||
   286 		    (type == INCLUDENEXTDOT) ||
   287 		    (*include == '/')) {
   288 			if (does_file_exist(include))
   289 				return newinclude(include, include);
   290 			if (show_where_not)
   291 				warning1("\tnot in %s\n", include);
   292 		}
   294 		/*
   295 		 * If the path was surrounded by "" see if this include file is
   296 		 * in the directory of the file being parsed.
   297 		 */
   298 		if ((type == INCLUDEDOT) || (type == INCLUDENEXTDOT)) {
   299 			for (p=file+strlen(file); p>file; p--)
   300 				if (*p == '/')
   301 					break;
   302 			if (p == file) {
   303 				strcpy(path, include);
   304 			} else {
   305 				strncpy(path, file, (p-file) + 1);
   306 				path[ (p-file) + 1 ] = '\0';
   307 				strcpy(path + (p-file) + 1, include);
   308 			}
   309 			remove_dotdot(path);
   310 			if (does_file_exist(path))
   311 				return newinclude(path, include);
   312 			if (show_where_not)
   313 				warning1("\tnot in %s\n", path);
   314 		}
   315 	}
   317 	/*
   318 	 * Check the include directories specified.  Standard include dirs
   319 	 * should be at the end.
   320 	 */
   321 	if ((type == INCLUDE) || (type == INCLUDEDOT))
   322 		includedirsnext = includedirs;
   323 	pp = includedirsnext;
   325 	for (; *pp; pp++) {
   326 		sprintf(path, "%s/%s", *pp, include);
   327 		remove_dotdot(path);
   328 		if (does_file_exist(path)) {
   329 			includedirsnext = pp + 1;
   330 			return newinclude(path, include);
   331 		}
   332 		if (show_where_not)
   333 			warning1("\tnot in %s\n", path);
   334 	}
   336 	return NULL;
   337 }

mercurial