[binutils-gdb] bfd: correct dir separator conversion for Win32

Jan Beulich jbeulich@sourceware.org
Fri Dec 19 07:55:07 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=3f89802f207adad4f2f0b8e0f60c44d77727af42

commit 3f89802f207adad4f2f0b8e0f60c44d77727af42
Author: Jan Beulich <jbeulich@suse.com>
Date:   Fri Dec 19 08:51:51 2025 +0100

    bfd: correct dir separator conversion for Win32
    
    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.

Diff:
---
 bfd/bfdio.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index 6bd7a2422de..21e864d1318 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -122,7 +122,6 @@ _bfd_real_fopen (const char *filename, const char *modes)
   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, const char *modes)
 
   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, const char *modes)
   /* 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-cvs mailing list