aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <[email protected]>2025-04-16 16:22:46 +0000
committerWerner Koch <[email protected]>2025-04-16 16:22:46 +0000
commit28ae4ee194ec56e98123d3aceda130161dfd2df8 (patch)
tree9503b7655d8a6adeedc92508297527c18b9eab1d
parentAdd command --fopen to gpg-error to help testing (diff)
downloadlibgpg-error-28ae4ee194ec56e98123d3aceda130161dfd2df8.tar.gz
libgpg-error-28ae4ee194ec56e98123d3aceda130161dfd2df8.zip
w32: Fix extended length path handling for UNC specified files.
* src/sysutils.c (_gpgrt_fname_to_wchar): Fix the extended length path support for UNC file names. Also add an envvar to disable the entire extended length path support. -- GnuPG-bug-id: 5754 Fixes-commit: a4a692fcf1ed128693ec6d64d5e3163775aad10b With the last fix we fixed the extended length path support but it also truned outa wrong implementaion of it for UNC. Before the previous patch the UNC support was already wrong but it exhibited itself only when the requested UNC was already long. The patch then kicked in the support more often and in particular always if an UNC was used (due to the new checking for backslashes and not just the length). To avoid further surprises we now have an envvar to disable that support entirely. But if should be correct now ;-).
-rw-r--r--src/sysutils.c30
1 files changed, 26 insertions, 4 deletions
diff --git a/src/sysutils.c b/src/sysutils.c
index 132f1d3..7bebd4b 100644
--- a/src/sysutils.c
+++ b/src/sysutils.c
@@ -263,15 +263,27 @@ _gpgrt_setenv (const char *name, const char *value, int overwrite)
wchar_t *
_gpgrt_fname_to_wchar (const char *fname)
{
+ static int no_extlenpath;
wchar_t *wname;
wchar_t *wfullpath = NULL;
int success = 0;
+ if (!no_extlenpath)
+ {
+ const char *s = getenv ("GPGRT_DISABLE_EXTLENPATH");
+ if (s && atoi (s))
+ no_extlenpath = 1;
+ else
+ no_extlenpath = -1;
+ }
+
wname = _gpgrt_utf8_to_wchar (fname);
if (!wname)
return NULL;
- if (!strncmp (fname, "\\\\?\\", 4))
+ if (no_extlenpath > 0)
+ success = 1; /* Extended length path support has been disabled. */
+ else if (!strncmp (fname, "\\\\?\\", 4) || !strncmp (fname, "//?/", 4))
success = 1; /* Already translated. */
else if (strpbrk (fname, "/\\") || wcslen (wname) > 60)
{
@@ -285,10 +297,16 @@ _gpgrt_fname_to_wchar (const char *fname)
if (!wfullpath)
goto leave;
- if (*fname == '\\' && fname[1] == '\\' && fname[2])
+ if (((*fname == '\\' && fname[1] == '\\')
+ ||(*fname == '/' && fname[1] == '/')) && fname[2])
{
- wcscpy (wfullpath, L"\\\\?\\UNC\\");
- extralen = 8;
+ /* Note that the GFPN call below will append the UNC name
+ * and thus two leading backslashes. However, for an
+ * extended length path only one backslash is expected after
+ * the prefix. We handle this by replacing the first
+ * backslash with the C from UNC after the GFPN call. */
+ wcscpy (wfullpath, L"\\\\?\\UN");
+ extralen = 6;
}
else
{
@@ -319,6 +337,10 @@ _gpgrt_fname_to_wchar (const char *fname)
_gpgrt_free_wchar (wname);
wname = wfullpath;
wfullpath = NULL;
+
+ if (extralen == 6)
+ wname[6] = 'C'; /* Replace first backslash - see above. */
+
/* Need to make sure that all slashes are mapped. */
for (w = wname; *w; w++)
if (*w == L'/')