[PATCH] bfd: correct dir separator conversion for Win32
Jan Beulich
jbeulich@suse.com
Fri Dec 5 09:29:08 GMT 2025
Iterating a wchar_t array holding the conversion of multi-byte (likely
UTF-8) input using array indexes from the corresponding char array isn't
going to work as soon as any characters wider than a single char are
present. Simply walk the wchar_t array all by itself.
While looking at that code I also noticed a wrong argument being passed to
a later MultiByteToWideChar() invocation: This needs to be number of
characters, which isn't sizeof() when the array is of wchar_t elements.
---
Note: I've only been able to build-test this, and even that in only a
contrived way (as I have no MinGW environment available). Sadly the
reporter of the issue hasn't responded back.
Note: Error handling is completely lacking here; this will need taking
care of separately, though.
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -122,7 +122,6 @@ _bfd_real_fopen (const char *filename, c
const wchar_t prefixDOS[] = L"\\\\?\\";
const wchar_t prefixUNC[] = L"\\\\?\\UNC\\";
const wchar_t prefixNone[] = L"";
- const size_t partPathLen = strlen (filename) + 1;
const wchar_t * prefix;
size_t sizeof_prefix;
bool strip_network_prefix = false;
@@ -207,10 +206,12 @@ _bfd_real_fopen (const char *filename, c
MultiByteToWideChar (cp, 0, filename, -1, partPath, partPathWSize);
- /* Convert any UNIX style path separators into the DOS i.e. backslash separator. */
- for (ix = 0; ix < partPathLen; ix++)
- if (IS_UNIX_DIR_SEPARATOR(filename[ix]))
- partPath[ix] = '\\';
+ /* Convert any UNIX style path separators into the DOS i.e. backslash
+ separator. Short of a TOASCII()- or ISASCII()-like helper (taking
+ wchar_t as input) in libiberty, open-code that here for now. */
+ for (ix = 0; partPath[ix] != L'\0'; ix++)
+ if (partPath[ix] <= L'\x7f' && IS_UNIX_DIR_SEPARATOR ((char)partPath[ix]))
+ partPath[ix] = L'\\';
/* Getting the full path from the provided partial path.
1) Get the length.
@@ -245,7 +246,7 @@ _bfd_real_fopen (const char *filename, c
/* It is non-standard for modes to exceed 16 characters. */
wchar_t modesW[16];
- MultiByteToWideChar (cp, 0, modes, -1, modesW, sizeof(modesW));
+ MultiByteToWideChar (cp, 0, modes, -1, modesW, ARRAY_SIZE (modesW));
FILE * file = _wfopen (fullPath, modesW);
free (fullPath);
More information about the Binutils
mailing list