bfd: handle codepage when opening files on MinGW

Even if MS docs say that CP_UTF8 should always be used on newer
applications, forcing it might produce undefined filename if the
encoding isn't UTF-8.
MinGW seems to call ___lc_codepage_func() in order to retrieve the
current thread codepage.

bfd/ChangeLog:

        * bfdio.c (_bfd_real_fopen): Retrieve codepage with
        ___lc_codepage_func() on MinGW.
This commit is contained in:
Clément Chigot
2022-06-28 09:42:12 +02:00
parent fadaf8f7f9
commit 68e80d96a8

View File

@ -28,6 +28,7 @@
#include "aout/ar.h" #include "aout/ar.h"
#if defined (_WIN32) #if defined (_WIN32)
#include <windows.h> #include <windows.h>
#include <locale.h>
#endif #endif
#ifndef S_IXUSR #ifndef S_IXUSR
@ -120,15 +121,20 @@ _bfd_real_fopen (const char *filename, const char *modes)
wchar_t ** lpFilePart = {NULL}; wchar_t ** lpFilePart = {NULL};
const wchar_t prefix[] = L"\\\\?\\"; const wchar_t prefix[] = L"\\\\?\\";
const size_t partPathLen = strlen (filename) + 1; const size_t partPathLen = strlen (filename) + 1;
#ifdef __MINGW32__
const unsigned int cp = ___lc_codepage_func();
#else
const unsigned int cp = CP_UTF8;
#endif
/* Converting the partial path from ascii to unicode. /* Converting the partial path from ascii to unicode.
1) Get the length: Calling with lpWideCharStr set to null returns the length. 1) Get the length: Calling with lpWideCharStr set to null returns the length.
2) Convert the string: Calling with cbMultiByte set to -1 includes the terminating null. */ 2) Convert the string: Calling with cbMultiByte set to -1 includes the terminating null. */
size_t partPathWSize = MultiByteToWideChar (CP_UTF8, 0, filename, -1, NULL, 0); size_t partPathWSize = MultiByteToWideChar (cp, 0, filename, -1, NULL, 0);
wchar_t * partPath = calloc (partPathWSize, sizeof(wchar_t)); wchar_t * partPath = calloc (partPathWSize, sizeof(wchar_t));
size_t ix; size_t ix;
MultiByteToWideChar (CP_UTF8, 0, filename, -1, partPath, partPathWSize); MultiByteToWideChar (cp, 0, filename, -1, partPath, partPathWSize);
/* Convert any UNIX style path separators into the DOS i.e. backslash separator. */ /* Convert any UNIX style path separators into the DOS i.e. backslash separator. */
for (ix = 0; ix < partPathLen; ix++) for (ix = 0; ix < partPathLen; ix++)
@ -152,7 +158,7 @@ _bfd_real_fopen (const char *filename, const char *modes)
/* It is non-standard for modes to exceed 16 characters. */ /* It is non-standard for modes to exceed 16 characters. */
wchar_t modesW[16]; wchar_t modesW[16];
MultiByteToWideChar (CP_UTF8, 0, modes, -1, modesW, sizeof(modesW)); MultiByteToWideChar (cp, 0, modes, -1, modesW, sizeof(modesW));
FILE * file = _wfopen (fullPath, modesW); FILE * file = _wfopen (fullPath, modesW);
free (fullPath); free (fullPath);