]> Savannah Git Hosting - gnulib.git/commitdiff
canonicalize: Add support for UNC file names on native Windows.
authorBruno Haible <bruno@clisp.org>
Sun, 20 Sep 2020 22:52:26 +0000 (00:52 +0200)
committerBruno Haible <bruno@clisp.org>
Sun, 20 Sep 2020 22:52:26 +0000 (00:52 +0200)
Reported and initial patch by Vaclav Slavik <vaclav@slavik.io> in
<https://savannah.gnu.org/bugs/?59079>.

* lib/canonicalize.c (canonicalize_filename_mode): For UNC file names,
extend the prefix to include the server.

ChangeLog
lib/canonicalize.c

index 167c7e78931823b6caee8444513ac4ee64b162c8..4fdd1a778c659d5314c9fece3853395bb9be06aa 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2020-09-20  Bruno Haible  <bruno@clisp.org>
+
+       canonicalize: Add support for UNC file names on native Windows.
+       Reported and initial patch by Vaclav Slavik <vaclav@slavik.io> in
+       <https://savannah.gnu.org/bugs/?59079>.
+       * lib/canonicalize.c (canonicalize_filename_mode): For UNC file names,
+       extend the prefix to include the server.
+
 2020-09-20  Bruno Haible  <bruno@clisp.org>
 
        supersede: Fix test failures on native Windows.
index aa0c3bd280a1280133229082270f0bc4e2108e11..1fb3878ef2a8ffe6f99c3d3ca774a542a08ef56b 100644 (file)
@@ -163,8 +163,34 @@ canonicalize_filename_mode (const char *name, canonicalize_mode_t can_mode)
       *dest++ = '/';
       if (DOUBLE_SLASH_IS_DISTINCT_ROOT)
         {
-          if (ISSLASH (name[1]) && !ISSLASH (name[2]) && !prefix_len)
-            *dest++ = '/';
+          if (prefix_len == 0 /* implies ISSLASH (name[0]) */
+              && ISSLASH (name[1]) && !ISSLASH (name[2]))
+            {
+              *dest++ = '/';
+#if defined _WIN32 && !defined __CYGWIN__
+              /* For UNC file names '\\server\path\to\file', extend the prefix
+                 to include the server: '\\server\'.  */
+              {
+                size_t i;
+                for (i = 2; name[i] != '\0' && !ISSLASH (name[i]); )
+                  i++;
+                if (name[i] != '\0' /* implies ISSLASH (name[i]) */
+                    && i + 1 < rname_limit - rname)
+                  {
+                    prefix_len = i;
+                    memcpy (dest, name + 2, i - 2 + 1);
+                    dest += i - 2 + 1;
+                  }
+                else
+                  {
+                    /* Either name = '\\server'; this is an invalid file name.
+                       Or name = '\\server\...' and server is more than
+                       PATH_MAX - 4 bytes long.  In either case, stop the UNC
+                       processing.  */
+                  }
+              }
+#endif
+            }
           *dest = '\0';
         }
       start = name + prefix_len;