[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
canonicalize: Add support for UNC file names on native Windows
From: |
Bruno Haible |
Subject: |
canonicalize: Add support for UNC file names on native Windows |
Date: |
Mon, 21 Sep 2020 00:49:51 +0200 |
User-agent: |
KMail/5.1.3 (Linux/4.4.0-189-generic; KDE/5.18.0; x86_64; ; ) |
Through the 'supersede' module, gettext now uses the 'canonicalize' module.
Vaclav Slavik reported in <https://savannah.gnu.org/bugs/?59079>:
"msgfmt ... to unmounted shared folders on Windows via UNC paths
(e.g. \\localhost\sharedfolder) fails. I got multiple reports of this
pretty quickly, so it's not as obscure an edge case as one could be
excused to think.
This is because fopen_supersede() uses canonicalize_filename_mode() which
doesn't handle this situation correctly. While it has code in place to
recognize leading double-slash as being different from single-slash, and
knows that this applies to win32, that's it. It then traverses the entire
path from the root, stat()ing each path component - but the initial part,
\\hostname, is not stat()able, it's not a path; \\hostname\foo is the
first real component.
Attached patch fixes this to the best of my understanding of how
canonicalize_filename_mode() works: it increases `prefix_len` (which
is bound to be 0 for \\paths) to cover the hostname component, and copies
the hostname part to `dest` as well - causing canonicalization to start
at the first real path component and keep the leading \\hostname\ bit
constant. "
I modified Vaclav's patch to include out-of-bounds handling, and to make
prefix_len point to the slash/backslash after the server name (rather than
past this slash/backslash). Tested with file names of the form
\\localhost\foo -> //localhost\foo
\\localhost\.\foo -> //localhost\foo
\\localhost\..\foo -> //localhost\foo
\\localhost -> //localhost
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.
diff --git a/lib/canonicalize.c b/lib/canonicalize.c
index aa0c3bd..dfdb912 100644
--- a/lib/canonicalize.c
+++ b/lib/canonicalize.c
@@ -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;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- canonicalize: Add support for UNC file names on native Windows,
Bruno Haible <=