Blame SOURCES/gcc34-rh137200.patch

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