https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=57573812ed0beb5c92717a7fcfe665c7b54b5d70
commit 57573812ed0beb5c92717a7fcfe665c7b54b5d70 Author: Corinna Vinschen <cori...@vinschen.de> AuthorDate: Fri Jun 27 17:32:32 2025 +0200 Commit: Corinna Vinschen <cori...@vinschen.de> CommitDate: Fri Jun 27 17:33:12 2025 +0200 Cygwin: drop ASCII NUL from invalid DOS filename char transposition table The mechanism to convert characters invalid in DOS/Windows filenames to the Unicode private use area starting at 0xf000 accidentally also converts ASCII NUL to the private use area. That usually doesn't happen, but what if the filename contains the 0xf000 character and we want to convert it back to multibyte? In this case the 0xf000 becomes the ASCII NUL again, and the resulting string is cut short and does not match with the real filename. This leads to all sorts of problems like the inability to unlink the file. Fix this problem by not marking ASCII NUL as transposable character. This problem has been introduced by adding code to support abstract sockets which may contain a NUL char as part of the socket name. By reverting the ASCII NUL in the transposition tables, transform_chars_af_unix has to handle ASCII NUL explicitely now. Reported-by: Christian Franke <christian.fra...@t-online.de> Addresses: https://cygwin.com/pipermail/cygwin/2025-June/258367.html Fixes: 7d260cfac42d ("Cygwin: add transform_chars_af_unix helper") Signed-off-by: Corinna Vinschen <cori...@vinschen.de> (cherry picked from commit 61e38a8fe0270797b4c9b9f2e2ce33265d498aac) Diff: --- winsup/cygwin/strfuncs.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/winsup/cygwin/strfuncs.cc b/winsup/cygwin/strfuncs.cc index 66667bdb3a3c..cb7911c6b83d 100644 --- a/winsup/cygwin/strfuncs.cc +++ b/winsup/cygwin/strfuncs.cc @@ -23,7 +23,7 @@ details. */ is affected as well, but we can't transform it as long as we accept Win32 paths as input. */ static const WCHAR tfx_chars[] = { - 0xf000 | 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, + 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, 0xf000 | 4, 0xf000 | 5, 0xf000 | 6, 0xf000 | 7, 0xf000 | 8, 0xf000 | 9, 0xf000 | 10, 0xf000 | 11, 0xf000 | 12, 0xf000 | 13, 0xf000 | 14, 0xf000 | 15, @@ -62,7 +62,7 @@ static const WCHAR tfx_chars[] = { converting back space and dot on filesystems only supporting DOS filenames. */ static const WCHAR tfx_rev_chars[] = { - 0xf000 | 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, + 0, 0xf000 | 1, 0xf000 | 2, 0xf000 | 3, 0xf000 | 4, 0xf000 | 5, 0xf000 | 6, 0xf000 | 7, 0xf000 | 8, 0xf000 | 9, 0xf000 | 10, 0xf000 | 11, 0xf000 | 12, 0xf000 | 13, 0xf000 | 14, 0xf000 | 15, @@ -109,7 +109,7 @@ transform_chars_af_unix (PWCHAR out, const char *path, __socklen_t len) { len -= sizeof (__sa_family_t); for (const unsigned char *p = (const unsigned char *) path; len-- > 0; ++p) - *out++ = (*p <= 0x7f) ? tfx_chars[*p] : *p; + *out++ = (*p <= 0x7f) ? (*p == 0) ? 0xf000 : tfx_chars[*p] : *p; return out; }