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 <[email protected]>
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public