On 2025-05-10 Pali Rohár wrote: > Just cosmetic comment: It seems that this file uses coding style which > put { on a new line after while keyword and also put two spaces > before {.
Thanks! I attached an updated patch that has this fixed. The first if-statement in the file already has { on the same line. I didn't modify that. There's also some inconsistency between "char *foo" and "char* foo". -- Lasse Collin
>From b15762687956b985a4575fe5e90bf8273f453245 Mon Sep 17 00:00:00 2001 From: Lasse Collin <lasse.col...@tukaani.org> Date: Thu, 8 May 2025 16:20:05 +0300 Subject: [PATCH v2 6/7] crt: stat: Don't remove a trailing '\' if it is a DBCS trail byte In double-byte character sets, the trail byte of a two-byte character can be a backslash. If such a two-byte character was at the end of the pathname, the trailing backslash was incorrectly removed. The code still removes only one trailing directory separator and thus stat("directory//", &st) still incorrectly fails with MSVCRT. This commit only fixes the DBCS issue. --- mingw-w64-crt/stdio/__mingw_fix_stat_path.c | 36 ++++++++++++++++++--- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/mingw-w64-crt/stdio/__mingw_fix_stat_path.c b/mingw-w64-crt/stdio/__mingw_fix_stat_path.c index 7614491a9..b853d1d1e 100644 --- a/mingw-w64-crt/stdio/__mingw_fix_stat_path.c +++ b/mingw-w64-crt/stdio/__mingw_fix_stat_path.c @@ -4,10 +4,22 @@ * No warranty is given; refer to the file DISCLAIMER.PD within this package. */ +#ifndef WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif #include <sys/stat.h> #include <stdlib.h> +#include <locale.h> +#include <windows.h> #include "__mingw_fix_stat.h" +static const char* next_char (unsigned int cp, const char* p) +{ + /* If it is a lead byte, skip the next byte except if it is \0. + * If it is \0, it's not a valid DBCS string. */ + return (IsDBCSLeadByteEx (cp, *p) && p[1] != '\0') ? p + 2 : p + 1; +} + /** * Returns _path without trailing slash if any * @@ -20,6 +32,7 @@ char* __mingw_fix_stat_path (const char* _path) { + const unsigned int cp = __mingw_filename_cp (); size_t len; char *p; @@ -28,24 +41,27 @@ char* __mingw_fix_stat_path (const char* _path) if (_path && *_path) { len = strlen (_path); - /* Ignore X:\ */ - + /* Ignore X:\ + * No ANSI or OEM code page uses ':' as a trail byte. (The code page 1361 + * cannot be used as ANSI or OEM code page.) */ if (len <= 1 || ((len == 2 || len == 3) && _path[1] == ':')) return p; + const char *r = _path; + /* Check UNC \\abc\<name>\ */ if ((_path[0] == '\\' || _path[0] == '/') && (_path[1] == '\\' || _path[1] == '/')) { - const char *r = &_path[2]; + r = &_path[2]; while (*r != 0 && *r != '\\' && *r != '/') - ++r; + r = next_char (cp, r); if (*r != 0) ++r; if (*r == 0) return p; while (*r != 0 && *r != '\\' && *r != '/') - ++r; + r = next_char (cp, r); if (*r != 0) ++r; if (*r == 0) @@ -54,6 +70,16 @@ char* __mingw_fix_stat_path (const char* _path) if (_path[len - 1] == '/' || _path[len - 1] == '\\') { + /* Return if the last character is a double-byte character. + * Its trail byte could be a '\' which must not be interpret + * as a directory separator. */ + while (r[1] != '\0') + { + r = next_char (cp, r); + if (*r == '\0') + return p; + } + p = (char*)malloc (len); if (p == NULL) return NULL; /* malloc has set errno. */ -- 2.49.0
_______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public