bug-gnulib
[Top][All Lists]
Advanced

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

Re: canonicalize_file_name does not support MS-Windows style file names


From: Eli Zaretskii
Subject: Re: canonicalize_file_name does not support MS-Windows style file names
Date: Wed, 21 Nov 2012 20:31:41 +0200

I found a bug, so I'm attaching a patch to fix it.  The list of test
cases is now this:

     'foo.bar' => 'd:\usr\eli\utils\lib/foo.bar'
     '.\foo.bar' => 'd:\usr\eli\utils\lib/foo.bar'
     './foo.bar' => 'd:\usr\eli\utils\lib/foo.bar'
     '..\foo.bar' => 'd:\usr\eli\utils\foo.bar'
     '../foo.bar' => 'd:\usr\eli\utils\foo.bar'
     '../CURDIR/foo.bar' => 'd:\usr\eli\utils\CURDIR/foo.bar'
     '..\CURDIR\foo.bar' => 'd:\usr\eli\utils\CURDIR/foo.bar'
     '..\CURDIR/foo.bar' => 'd:\usr\eli\utils\CURDIR/foo.bar'
     '..\CURDIR\foo.bar\' => '(null)'
     '../CURDIR\foo.bar' => 'd:\usr\eli\utils\CURDIR/foo.bar'
     'C:WINDOWS' => '(null)'
     'C:system32' => '(null)'
     'C:/WINDOWS' => 'C:/WINDOWS'
     'C:\WINDOWS' => 'C:/WINDOWS'
     'C:\\WINDOWS' => 'C:/WINDOWS'
     'C:./WINDOWS' => '(null)'
     'C:./system32' => '(null)'
     'C:.\WINDOWS' => '(null)'
     'C:.\system32' => '(null)'
     'C:.' => 'd:\usr\eli\utils\lib'
     'C:/' => 'C:/'
     'C:\' => 'C:/'

Here's the patch relative to the latest gnulib version:

2012-11-21  Eli Zaretskii  <address@hidden>

        * canonicalize-lgpl.c (__realpath): Recompute prefix_len after
        fetching the current directory.  Don't overrun the beginning of
        rpath if there's no slashes after the MS-Windows drive letter.

        * canonicalize.c (canonicalize_filename_mode): Recompute
        prefix_len after fetching the current directory.  Don't
        overrun the beginning of rname if there's no slashes after the
        MS-Windows drive letter.


--- canonicalize-lgpl.c~1       2012-11-21 06:45:02.000000000 +0200
+++ canonicalize-lgpl.c 2012-11-21 07:50:41.626852500 +0200
@@ -157,6 +157,8 @@ __realpath (const char *name, char *reso
           goto error;
         }
       dest = strchr (rpath, '\0');
+      start = name;
+      prefix_len = FILE_SYSTEM_PREFIX_LEN (rpath);
     }
   else
     {
@@ -173,9 +175,10 @@ __realpath (const char *name, char *reso
             *dest++ = '/';
           *dest = '\0';
         }
+      start = name + prefix_len;
     }
 
-  for (start = end = name + prefix_len; *start; start = end)
+  for (end = start; *start; start = end)
     {
 #ifdef _LIBC
       struct stat64 st;
@@ -200,7 +203,7 @@ __realpath (const char *name, char *reso
         {
           /* Back up to previous component, ignore if at root already.  */
           if (dest > rpath + prefix_len + 1)
-            for (--dest; !ISSLASH (dest[-1]); --dest)
+            for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
               continue;
           if (DOUBLE_SLASH_IS_DISTINCT_ROOT
               && dest == rpath + 1 && !prefix_len
@@ -334,7 +337,7 @@ __realpath (const char *name, char *reso
                   /* Back up to previous component, ignore if at root
                      already: */
                   if (dest > rpath + prefix_len + 1)
-                    for (--dest; !ISSLASH (dest[-1]); --dest)
+                    for (--dest; dest > rpath && !ISSLASH (dest[-1]); --dest)
                       continue;
                   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rpath + 1
                       && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)


--- canonicalize.c~1    2012-11-21 06:45:02.000000000 +0200
+++ canonicalize.c      2012-11-21 07:52:42.324052500 +0200
@@ -150,6 +150,8 @@ canonicalize_filename_mode (const char *
         {
           rname_limit = dest;
         }
+      start = name;
+      prefix_len = FILE_SYSTEM_PREFIX_LEN (rname);
     }
   else
     {
@@ -168,9 +170,10 @@ canonicalize_filename_mode (const char *
             *dest++ = '/';
           *dest = '\0';
         }
+      start = name + prefix_len;
     }
 
-  for (start = name + prefix_len; *start; start = end)
+  for ( ; *start; start = end)
     {
       /* Skip sequence of multiple file name separators.  */
       while (ISSLASH (*start))
@@ -188,7 +191,7 @@ canonicalize_filename_mode (const char *
         {
           /* Back up to previous component, ignore if at root already.  */
           if (dest > rname + prefix_len + 1)
-            for (--dest; !ISSLASH (dest[-1]); --dest)
+            for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
               continue;
           if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
               && !prefix_len && ISSLASH (*dest) && !ISSLASH (dest[1]))
@@ -308,7 +311,7 @@ canonicalize_filename_mode (const char *
                   /* Back up to previous component, ignore if at root
                      already: */
                   if (dest > rname + prefix_len + 1)
-                    for (--dest; !ISSLASH (dest[-1]); --dest)
+                    for (--dest; dest > rname && !ISSLASH (dest[-1]); --dest)
                       continue;
                   if (DOUBLE_SLASH_IS_DISTINCT_ROOT && dest == rname + 1
                       && ISSLASH (*dest) && !ISSLASH (dest[1]) && !prefix_len)



reply via email to

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