Blame SOURCES/gcc34-rh137200.patch

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