emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] Changes to emacs/src/fileio.c,v


From: Stefan Monnier
Subject: [Emacs-diffs] Changes to emacs/src/fileio.c,v
Date: Sat, 12 Apr 2008 05:12:19 +0000

CVSROOT:        /sources/emacs
Module name:    emacs
Changes by:     Stefan Monnier <monnier>        08/04/12 05:12:18

Index: fileio.c
===================================================================
RCS file: /sources/emacs/emacs/src/fileio.c,v
retrieving revision 1.611
retrieving revision 1.612
diff -u -b -r1.611 -r1.612
--- fileio.c    10 Apr 2008 20:35:25 -0000      1.611
+++ fileio.c    12 Apr 2008 05:12:18 -0000      1.612
@@ -1042,11 +1042,13 @@
      (name, default_directory)
      Lisp_Object name, default_directory;
 {
-  unsigned char *nm;
+  /* These point to SDATA and need to be careful with string-relocation
+     during GC (via DECODE_FILE).  */
+  unsigned char *nm, *newdir;
+  /* This should only point to alloca'd data.  */
+  unsigned char *target;
 
-  register unsigned char *newdir, *p, *o;
   int tlen;
-  unsigned char *target;
   struct passwd *pw;
 #ifdef VMS
   unsigned char * colon = 0;
@@ -1103,7 +1105,8 @@
        return call3 (handler, Qexpand_file_name, name, default_directory);
     }
 
-  o = SDATA (default_directory);
+  {
+    unsigned char *o = SDATA (default_directory);
 
   /* Make sure DEFAULT_DIRECTORY is properly expanded.
      It would be better to do this down below where we actually use
@@ -1121,7 +1124,8 @@
         is needed at all) without requiring it to be expanded now.  */
 #ifdef DOS_NT
       /* Detect MSDOS file names with drive specifiers.  */
-      && ! (IS_DRIVE (o[0]) && IS_DEVICE_SEP (o[1]) && IS_DIRECTORY_SEP (o[2]))
+       && ! (IS_DRIVE (o[0]) && IS_DEVICE_SEP (o[1])
+             && IS_DIRECTORY_SEP (o[2]))
 #ifdef WINDOWSNT
       /* Detect Windows file names in UNC format.  */
       && ! (IS_DIRECTORY_SEP (o[0]) && IS_DIRECTORY_SEP (o[1]))
@@ -1139,7 +1143,7 @@
       default_directory = Fexpand_file_name (default_directory, Qnil);
       UNGCPRO;
     }
-
+  }
   name = FILE_SYSTEM_CASE (name);
   multibyte = STRING_MULTIBYTE (name);
   if (multibyte != STRING_MULTIBYTE (default_directory))
@@ -1182,16 +1186,14 @@
      "//somedir".  */
   if (drive && IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
     nm++;
-#endif /* WINDOWSNT */
-#endif /* DOS_NT */
 
-#ifdef WINDOWSNT
   /* Discard any previous drive specifier if nm is now in UNC format. */
   if (IS_DIRECTORY_SEP (nm[0]) && IS_DIRECTORY_SEP (nm[1]))
     {
       drive = 0;
     }
-#endif
+#endif /* WINDOWSNT */
+#endif /* DOS_NT */
 
   /* If nm is absolute, look for `/./' or `/../' or `//''sequences; if
      none are found, we can probably return right away.  We will avoid
@@ -1216,8 +1218,8 @@
         non-zero value, that means we've discovered that we can't do
         that cool trick.  */
       int lose = 0;
+      unsigned char *p = nm;
 
-      p = nm;
       while (*p)
        {
          /* Since we know the name is absolute, we can assume that each
@@ -1389,8 +1391,12 @@
          tem = build_string (newdir);
          if (!STRING_MULTIBYTE (tem))
            {
+             /* FIXME: DECODE_FILE may GC, which may move SDATA(name),
+                after which `nm' won't point to the right place any more.  */
+             int offset = nm - SDATA (name);
              hdir = DECODE_FILE (tem);
              newdir = SDATA (hdir);
+             nm = SDATA (name) + offset;
            }
 #ifdef DOS_NT
          collapse_newdir = 0;
@@ -1401,12 +1407,13 @@
        }
       else                     /* ~user/filename */
        {
+         unsigned char *o, *p;
          for (p = nm; *p && (!IS_DIRECTORY_SEP (*p)
 #ifdef VMS
                              && *p != ':'
 #endif /* VMS */
                              ); p++);
-         o = (unsigned char *) alloca (p - nm + 1);
+         o = alloca (p - nm + 1);
          bcopy ((char *) nm, o, p - nm);
          o [p - nm] = 0;
 
@@ -1618,8 +1625,9 @@
   /* Now canonicalize by removing `//', `/.' and `/foo/..' if they
      appear.  */
 
-  p = target;
-  o = target;
+  {
+    unsigned char *p = target;
+    unsigned char *o = target;
 
   while (*p)
     {
@@ -1732,6 +1740,7 @@
 #endif /* DOS_NT */
 
   result = make_specified_string (target, -1, o - target, multibyte);
+  }
 
   /* Again look to see if the file name has special constructs in it
      and perhaps call the corresponding file handler.  This is needed




reply via email to

[Prev in Thread] Current Thread [Next in Thread]