Blame SOURCES/gcc34-rh137200.patch

4e62ec
2005-11-30  Alexandre Oliva  <aoliva@redhat.com>
4e62ec
4e62ec
	* gcc.c (find_a_file): Use update_path before access tests.
4e62ec
	Mostly from Thomas Walker <thomas.walker@morganstanley.com>
4e62ec
	* prefix.c (update_path): Move dir/../-stripping code to...
4e62ec
	(maybe_strip_dotdots): New function.  Reorganize.
4e62ec
4e62ec
--- gcc/gcc.c.orig	2005-12-01 18:38:38.000000000 -0200
4e62ec
+++ gcc/gcc.c	2005-12-01 18:41:01.000000000 -0200
4e62ec
@@ -2371,7 +2371,7 @@
4e62ec
 find_a_file (struct path_prefix *pprefix, const char *name, int mode,
4e62ec
 	     int multilib)
4e62ec
 {
4e62ec
-  char *temp;
4e62ec
+  char *temp, *temp2;
4e62ec
   const char *const file_suffix =
4e62ec
     ((mode & X_OK) != 0 ? HOST_EXECUTABLE_SUFFIX : "");
4e62ec
   struct prefix_list *pl;
4e62ec
@@ -2407,19 +2407,18 @@
4e62ec
 				    NULL));
4e62ec
     }
4e62ec
 
4e62ec
-  temp = xmalloc (len);
4e62ec
-
4e62ec
   /* Determine the filename to execute (special case for absolute paths).  */
4e62ec
 
4e62ec
   if (IS_ABSOLUTE_PATH (name))
4e62ec
     {
4e62ec
-      if (access (name, mode) == 0)
4e62ec
-	{
4e62ec
-	  strcpy (temp, name);
4e62ec
-	  return temp;
4e62ec
-	}
4e62ec
+      /* IS_ABSOLUTE_PATHNAME lets anything through that starts with '/'  */
4e62ec
+      temp = update_path (name, NULL);
4e62ec
+      if (access (temp, mode) == 0)
4e62ec
+	return temp;
4e62ec
     }
4e62ec
   else
4e62ec
+  {
4e62ec
+    temp = xmalloc (len);
4e62ec
     for (pl = pprefix->plist; pl; pl = pl->next)
4e62ec
       {
4e62ec
 	const char *this_name
4e62ec
@@ -2435,24 +2434,30 @@
4e62ec
 		strcat (temp, machine_suffix);
4e62ec
 		strcat (temp, multilib_name);
4e62ec
 		strcat (temp, file_suffix);
4e62ec
-		if (access_check (temp, mode) == 0)
4e62ec
+		temp2 = update_path (temp, NULL);
4e62ec
+		if (access_check (temp2, mode) == 0)
4e62ec
 		  {
4e62ec
 		    if (pl->used_flag_ptr != 0)
4e62ec
 		      *pl->used_flag_ptr = 1;
4e62ec
-		    return temp;
4e62ec
+		    free (temp);
4e62ec
+		    return temp2;
4e62ec
 		  }
4e62ec
+		free (temp2);
4e62ec
 	      }
4e62ec
 
4e62ec
 	    /* Now try just the multilib_name.  */
4e62ec
 	    strcpy (temp, pl->prefix);
4e62ec
 	    strcat (temp, machine_suffix);
4e62ec
 	    strcat (temp, multilib_name);
4e62ec
-	    if (access_check (temp, mode) == 0)
4e62ec
+	    temp2 = update_path (temp, NULL);
4e62ec
+	    if (access_check (temp2, mode) == 0)
4e62ec
 	      {
4e62ec
 		if (pl->used_flag_ptr != 0)
4e62ec
 		  *pl->used_flag_ptr = 1;
4e62ec
-		return temp;
4e62ec
+		free (temp);
4e62ec
+		return temp2;
4e62ec
 	      }
4e62ec
+	    free (temp2);
4e62ec
 	  }
4e62ec
 
4e62ec
 	/* Certain prefixes are tried with just the machine type,
4e62ec
@@ -2467,23 +2472,29 @@
4e62ec
 		strcat (temp, just_machine_suffix);
4e62ec
 		strcat (temp, multilib_name);
4e62ec
 		strcat (temp, file_suffix);
4e62ec
-		if (access_check (temp, mode) == 0)
4e62ec
+		temp2 = update_path (temp, NULL);
4e62ec
+		if (access_check (temp2, mode) == 0)
4e62ec
 		  {
4e62ec
 		    if (pl->used_flag_ptr != 0)
4e62ec
 		      *pl->used_flag_ptr = 1;
4e62ec
-		    return temp;
4e62ec
+		    free (temp);
4e62ec
+		    return temp2;
4e62ec
 		  }
4e62ec
+		free (temp2);
4e62ec
 	      }
4e62ec
 
4e62ec
 	    strcpy (temp, pl->prefix);
4e62ec
 	    strcat (temp, just_machine_suffix);
4e62ec
 	    strcat (temp, multilib_name);
4e62ec
-	    if (access_check (temp, mode) == 0)
4e62ec
+	    temp2 = update_path (temp, NULL);
4e62ec
+	    if (access_check (temp2, mode) == 0)
4e62ec
 	      {
4e62ec
 		if (pl->used_flag_ptr != 0)
4e62ec
 		  *pl->used_flag_ptr = 1;
4e62ec
-		return temp;
4e62ec
+		free (temp);
4e62ec
+		return temp2;
4e62ec
 	      }
4e62ec
+	    free (temp2);
4e62ec
 	  }
4e62ec
 
4e62ec
 	/* Certain prefixes can't be used without the machine suffix
4e62ec
@@ -2497,24 +2508,31 @@
4e62ec
 		strcpy (temp, pl->prefix);
4e62ec
 		strcat (temp, this_name);
4e62ec
 		strcat (temp, file_suffix);
4e62ec
-		if (access_check (temp, mode) == 0)
4e62ec
+		temp2 = update_path (temp, NULL);
4e62ec
+		if (access_check (temp2, mode) == 0)
4e62ec
 		  {
4e62ec
 		    if (pl->used_flag_ptr != 0)
4e62ec
 		      *pl->used_flag_ptr = 1;
4e62ec
-		    return temp;
4e62ec
+		    free (temp);
4e62ec
+		    return temp2;
4e62ec
 		  }
4e62ec
+		free (temp2);
4e62ec
 	      }
4e62ec
 
4e62ec
 	    strcpy (temp, pl->prefix);
4e62ec
 	    strcat (temp, this_name);
4e62ec
-	    if (access_check (temp, mode) == 0)
4e62ec
+	    temp2 = update_path (temp, NULL);
4e62ec
+	    if (access_check (temp2, mode) == 0)
4e62ec
 	      {
4e62ec
 		if (pl->used_flag_ptr != 0)
4e62ec
 		  *pl->used_flag_ptr = 1;
4e62ec
-		return temp;
4e62ec
+		free (temp);
4e62ec
+		return temp2;
4e62ec
 	      }
4e62ec
+	    free (temp2);
4e62ec
 	  }
4e62ec
       }
4e62ec
+  }
4e62ec
 
4e62ec
   free (temp);
4e62ec
   return 0;
4e62ec
--- gcc/prefix.c.orig	2005-12-01 18:38:38.000000000 -0200
4e62ec
+++ gcc/prefix.c	2005-12-01 18:46:37.000000000 -0200
4e62ec
@@ -238,6 +238,105 @@
4e62ec
   while (*string++);
4e62ec
 }
4e62ec
 
4e62ec
+/* Strip dir/.. from a pathname when it makes sense, e.g., when this
4e62ec
+   would turn an inaccessible pathname into an accessible one.
4e62ec
+
4e62ec
+   We short-circuit dir/.. when dir does not exist, and when
4e62ec
+   some/dir/../thing does not exist but some/thing does.  In case
4e62ec
+   there are multiple possible dir/../ stripping possibilities that
4e62ec
+   would turn an inaccessible pathname into an accessible one, the one
4e62ec
+   closer to the end of the pathname is preferred.
4e62ec
+
4e62ec
+   RESULT is the pathname that might contain such dotdot sequences to
4e62ec
+   be stripped.  P points into RESULT, and indicates the location
4e62ec
+   where we should start looking for ../ sequences.
4e62ec
+
4e62ec
+   Even though RESULT is const, P is not, and that's because
4e62ec
+   characters in it may be temporarily overwritten, so RESULT must not
4e62ec
+   be in read-only storage.
4e62ec
+
4e62ec
+   The returned value is either a newly-allocated memory area, holding
4e62ec
+   a string that is the result of dotdot-stripping from the original
4e62ec
+   input strip, or RESULT itself, in which case any modifications made
4e62ec
+   to the string will have been undone.  */
4e62ec
+
4e62ec
+static const char *
4e62ec
+maybe_strip_dotdots (const char *result, char *p)
4e62ec
+{
4e62ec
+  char *temp;
4e62ec
+  const char *path, *before, *after;
4e62ec
+  size_t len;
4e62ec
+
4e62ec
+  while (1)
4e62ec
+    {
4e62ec
+      p = strchr (p, '.');
4e62ec
+      if (p == NULL)
4e62ec
+	return result;
4e62ec
+      /* Look for `/../'  */
4e62ec
+      if (p[1] == '.'
4e62ec
+	  && IS_DIR_SEPARATOR (p[2])
4e62ec
+	  && (p != result && IS_DIR_SEPARATOR (p[-1])))
4e62ec
+	break;
4e62ec
+      else
4e62ec
+	++p;
4e62ec
+    }
4e62ec
+
4e62ec
+  *p = 0;
4e62ec
+  if (access (result, X_OK) == 0)
4e62ec
+    {
4e62ec
+      *p = '.';
4e62ec
+
4e62ec
+      path = maybe_strip_dotdots (result, p + 3);
4e62ec
+      if (access (path, F_OK) == 0)
4e62ec
+	return path;
4e62ec
+      if (path != result)
4e62ec
+	free ((char *) path);
4e62ec
+    }
4e62ec
+  else
4e62ec
+    *p = '.';
4e62ec
+
4e62ec
+  /* If we couldn't access the dir, or if recursion resulted in a
4e62ec
+     non-accessible pathname, we try stripping out dir/../.  If `dir'
4e62ec
+     turns out to be `.', strip one more path component.  */
4e62ec
+  before = p;
4e62ec
+  do
4e62ec
+    {
4e62ec
+      --before;
4e62ec
+      while (before != result && IS_DIR_SEPARATOR (*before))
4e62ec
+	--before;
4e62ec
+      while (before != result && !IS_DIR_SEPARATOR (before[-1]))
4e62ec
+	--before;
4e62ec
+    }
4e62ec
+  while (before != result && *before == '.'
4e62ec
+	 && IS_DIR_SEPARATOR (*(before + 1)));
4e62ec
+  /* If we have something like `./..' or `/..', don't
4e62ec
+     strip anything more.  */
4e62ec
+  if (*before == '.' || IS_DIR_SEPARATOR (*before))
4e62ec
+    return result;
4e62ec
+
4e62ec
+  after = p + 3;
4e62ec
+  while (IS_DIR_SEPARATOR (*after))
4e62ec
+    ++after;
4e62ec
+
4e62ec
+  len = (after - result) + strlen (after);
4e62ec
+
4e62ec
+  temp = xmalloc (len + 1 - (after - before));
4e62ec
+  memcpy (temp, result, before - result);
4e62ec
+  memcpy (temp + (before - result), after, len + 1 - (after - result));
4e62ec
+
4e62ec
+  path = maybe_strip_dotdots (temp, temp + (before - result));
4e62ec
+
4e62ec
+  if (path != temp)
4e62ec
+    free (temp);
4e62ec
+
4e62ec
+  if (access (path, F_OK) == 0)
4e62ec
+    result = path;
4e62ec
+  else if (path != result)
4e62ec
+    free ((char *) path);
4e62ec
+
4e62ec
+  return result;
4e62ec
+}
4e62ec
+
4e62ec
 /* Update PATH using KEY if PATH starts with PREFIX.  The returned
4e62ec
    string is always malloc-ed, and the caller is responsible for
4e62ec
    freeing it.  */
4e62ec
@@ -245,7 +344,7 @@
4e62ec
 char *
4e62ec
 update_path (const char *path, const char *key)
4e62ec
 {
4e62ec
-  char *result, *p;
4e62ec
+  char *result, *temp;
4e62ec
 
4e62ec
   if (! strncmp (path, std_prefix, strlen (std_prefix)) && key != 0)
4e62ec
     {
4e62ec
@@ -265,62 +364,11 @@
4e62ec
   else
4e62ec
     result = xstrdup (path);
4e62ec
 
4e62ec
-#ifndef ALWAYS_STRIP_DOTDOT
4e62ec
-#define ALWAYS_STRIP_DOTDOT 0
4e62ec
-#endif
4e62ec
+  temp = result;
4e62ec
+  result = (char *) maybe_strip_dotdots (temp, temp);
4e62ec
 
4e62ec
-  p = result;
4e62ec
-  while (1)
4e62ec
-    {
4e62ec
-      char *src, *dest;
4e62ec
-
4e62ec
-      p = strchr (p, '.');
4e62ec
-      if (p == NULL)
4e62ec
-	break;
4e62ec
-      /* Look for `/../'  */
4e62ec
-      if (p[1] == '.'
4e62ec
-	  && IS_DIR_SEPARATOR (p[2])
4e62ec
-	  && (p != result && IS_DIR_SEPARATOR (p[-1])))
4e62ec
-	{
4e62ec
-	  *p = 0;
4e62ec
-	  if (!ALWAYS_STRIP_DOTDOT && access (result, X_OK) == 0)
4e62ec
-	    {
4e62ec
-	      *p = '.';
4e62ec
-	      break;
4e62ec
-	    }
4e62ec
-	  else
4e62ec
-	    {
4e62ec
-	      /* We can't access the dir, so we won't be able to
4e62ec
-		 access dir/.. either.  Strip out `dir/../'.  If `dir'
4e62ec
-		 turns out to be `.', strip one more path component.  */
4e62ec
-	      dest = p;
4e62ec
-	      do
4e62ec
-		{
4e62ec
-		  --dest;
4e62ec
-		  while (dest != result && IS_DIR_SEPARATOR (*dest))
4e62ec
-		    --dest;
4e62ec
-		  while (dest != result && !IS_DIR_SEPARATOR (dest[-1]))
4e62ec
-		    --dest;
4e62ec
-		}
4e62ec
-	      while (dest != result && *dest == '.');
4e62ec
-	      /* If we have something like `./..' or `/..', don't
4e62ec
-		 strip anything more.  */
4e62ec
-	      if (*dest == '.' || IS_DIR_SEPARATOR (*dest))
4e62ec
-		{
4e62ec
-		  *p = '.';
4e62ec
-		  break;
4e62ec
-		}
4e62ec
-	      src = p + 3;
4e62ec
-	      while (IS_DIR_SEPARATOR (*src))
4e62ec
-		++src;
4e62ec
-	      p = dest;
4e62ec
-	      while ((*dest++ = *src++) != 0)
4e62ec
-		;
4e62ec
-	    }
4e62ec
-	}
4e62ec
-      else
4e62ec
-	++p;
4e62ec
-    }
4e62ec
+  if (result != temp)
4e62ec
+    free (temp);
4e62ec
 
4e62ec
 #ifdef UPDATE_PATH_HOST_CANONICALIZE
4e62ec
   /* Perform host dependent canonicalization when needed.  */