From: Junio C Hamano Date: Thu, 11 Jul 2019 22:16:49 +0000 (-0700) Subject: Merge branch 'js/mingw-use-utf8' X-Git-Tag: v2.23.0-rc0~43 X-Git-Url: https://git.lorimer.id.au/gitweb.git/diff_plain/0a2ff7c6b5ec5e4301a9cfb3c0dd26590d70ad7a?ds=inline;hp=-c Merge branch 'js/mingw-use-utf8' Windows update. * js/mingw-use-utf8: mingw: fix possible buffer overrun when calling `GetUserNameW()` mingw: use Unicode functions explicitly mingw: get pw_name in UTF-8 format --- 0a2ff7c6b5ec5e4301a9cfb3c0dd26590d70ad7a diff --combined compat/mingw.c index 433838391f,a0eb695653..4891789771 --- a/compat/mingw.c +++ b/compat/mingw.c @@@ -1407,7 -1407,7 +1407,7 @@@ static pid_t mingw_spawnve_fd(const cha do_unset_environment_variables(); /* Determine whether or not we are associated to a console */ - cons = CreateFile("CONOUT$", GENERIC_WRITE, + cons = CreateFileW(L"CONOUT$", GENERIC_WRITE, FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (cons == INVALID_HANDLE_VALUE) { @@@ -1553,10 -1553,7 +1553,10 @@@ static int try_shell_exec(const char *c if (prog) { int exec_id; int argc = 0; - const char **argv2; +#ifndef _MSC_VER + const +#endif + char **argv2; while (argv[argc]) argc++; ALLOC_ARRAY(argv2, argc + 1); argv2[0] = (char *)cmd; /* full path to the script file */ @@@ -1949,13 -1946,19 +1949,19 @@@ struct passwd *getpwuid(int uid static unsigned initialized; static char user_name[100]; static struct passwd *p; + wchar_t buf[100]; DWORD len; if (initialized) return p; - len = sizeof(user_name); - if (!GetUserName(user_name, &len)) { + len = ARRAY_SIZE(buf); + if (!GetUserNameW(buf, &len)) { + initialized = 1; + return NULL; + } + + if (xwcstoutf(user_name, buf, sizeof(user_name)) < 0) { initialized = 1; return NULL; } @@@ -2119,33 -2122,8 +2125,33 @@@ int mingw_raise(int sig sigint_fn(SIGINT); return 0; +#if defined(_MSC_VER) + case SIGILL: + case SIGFPE: + case SIGSEGV: + case SIGTERM: + case SIGBREAK: + case SIGABRT: + case SIGABRT_COMPAT: + /* + * The header in the MS C Runtime defines 8 signals + * as being supported on the platform. Anything else causes an + * "Invalid signal or error" (which in DEBUG builds causes the + * Abort/Retry/Ignore dialog). We by-pass the CRT for things we + * already know will fail. + */ + return raise(sig); + default: + errno = EINVAL; + return -1; + +#else + default: return raise(sig); + +#endif + } } @@@ -2329,13 -2307,18 +2335,13 @@@ static void setup_windows_environment(v setenv("TERM", "cygwin", 1); } +#if !defined(_MSC_VER) /* * Disable MSVCRT command line wildcard expansion (__getmainargs called from * mingw startup code, see init.c in mingw runtime). */ int _CRT_glob = 0; - -typedef struct { - int newmode; -} _startupinfo; - -extern int __wgetmainargs(int *argc, wchar_t ***argv, wchar_t ***env, int glob, - _startupinfo *si); +#endif static NORETURN void die_startup(void) { @@@ -2413,40 -2396,21 +2419,40 @@@ static void maybe_redirect_std_handles( GENERIC_WRITE, FILE_FLAG_NO_BUFFERING); } -void mingw_startup(void) +#ifdef _MSC_VER +#ifdef _DEBUG +#include +#endif +#endif + +/* + * We implement wmain() and compile with -municode, which would + * normally ignore main(), but we call the latter from the former + * so that we can handle non-ASCII command-line parameters + * appropriately. + * + * To be more compatible with the core git code, we convert + * argv into UTF8 and pass them directly to main(). + */ +int wmain(int argc, const wchar_t **wargv) { - int i, maxlen, argc; - char *buffer; - wchar_t **wenv, **wargv; - _startupinfo si; + int i, maxlen, exit_status; + char *buffer, **save; + const char **argv; trace2_initialize_clock(); - maybe_redirect_std_handles(); +#ifdef _MSC_VER +#ifdef _DEBUG + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG); +#endif - /* get wide char arguments and environment */ - si.newmode = 0; - if (__wgetmainargs(&argc, &wargv, &wenv, _CRT_glob, &si) < 0) - die_startup(); +#ifdef USE_MSVC_CRTDBG + _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); +#endif +#endif + + maybe_redirect_std_handles(); /* determine size of argv and environ conversion buffer */ maxlen = wcslen(wargv[0]); @@@ -2457,16 -2421,9 +2463,16 @@@ maxlen = 3 * maxlen + 1; buffer = malloc_startup(maxlen); - /* convert command line arguments and environment to UTF-8 */ + /* + * Create a UTF-8 version of w_argv. Also create a "save" copy + * to remember all the string pointers because parse_options() + * will remove claimed items from the argv that we pass down. + */ + ALLOC_ARRAY(argv, argc + 1); + ALLOC_ARRAY(save, argc + 1); for (i = 0; i < argc; i++) - __argv[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen); + argv[i] = save[i] = wcstoutfdup_startup(buffer, wargv[i], maxlen); + argv[i] = save[i] = NULL; free(buffer); /* fix Windows specific environment settings */ @@@ -2485,16 -2442,6 +2491,16 @@@ /* initialize Unicode console */ winansi_init(); + + /* invoke the real main() using our utf8 version of argv. */ + exit_status = main(argc, argv); + + for (i = 0; i < argc; i++) + free(save[i]); + free(save); + free(argv); + + return exit_status; } int uname(struct utsname *buf) diff --combined compat/poll/poll.c index 8b07edb0fe,8f24b80252..0e95dd493c --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@@ -149,8 -149,8 +149,8 @@@ win32_compute_revents (HANDLE h, int *p case FILE_TYPE_PIPE: if (!once_only) { - NtQueryInformationFile = (PNtQueryInformationFile) + NtQueryInformationFile = (PNtQueryInformationFile)(void (*)(void)) - GetProcAddress (GetModuleHandle ("ntdll.dll"), + GetProcAddress (GetModuleHandleW (L"ntdll.dll"), "NtQueryInformationFile"); once_only = TRUE; } diff --combined compat/winansi.c index efc0abcdac,cd947e048e..cacd82c833 --- a/compat/winansi.c +++ b/compat/winansi.c @@@ -7,7 -7,6 +7,7 @@@ #include #include #include "win32.h" +#include "win32/lazyload.h" static int fd_is_interactive[3] = { 0, 0, 0 }; #define FD_CONSOLE 0x1 @@@ -42,21 -41,26 +42,21 @@@ typedef struct _CONSOLE_FONT_INFOEX #endif #endif -typedef BOOL (WINAPI *PGETCURRENTCONSOLEFONTEX)(HANDLE, BOOL, - PCONSOLE_FONT_INFOEX); - static void warn_if_raster_font(void) { DWORD fontFamily = 0; - PGETCURRENTCONSOLEFONTEX pGetCurrentConsoleFontEx; + DECLARE_PROC_ADDR(kernel32.dll, BOOL, GetCurrentConsoleFontEx, + HANDLE, BOOL, PCONSOLE_FONT_INFOEX); /* don't bother if output was ascii only */ if (!non_ascii_used) return; /* GetCurrentConsoleFontEx is available since Vista */ - pGetCurrentConsoleFontEx = (PGETCURRENTCONSOLEFONTEX) GetProcAddress( - GetModuleHandle("kernel32.dll"), - "GetCurrentConsoleFontEx"); - if (pGetCurrentConsoleFontEx) { + if (INIT_PROC_ADDR(GetCurrentConsoleFontEx)) { CONSOLE_FONT_INFOEX cfi; cfi.cbSize = sizeof(cfi); - if (pGetCurrentConsoleFontEx(console, 0, &cfi)) + if (GetCurrentConsoleFontEx(console, 0, &cfi)) fontFamily = cfi.FontFamily; } else { /* pre-Vista: check default console font in registry */ @@@ -540,20 -544,7 +540,20 @@@ static HANDLE swap_osfhnd(int fd, HANDL #ifdef DETECT_MSYS_TTY #include + +#if defined(_MSC_VER) + +typedef struct _OBJECT_NAME_INFORMATION +{ + UNICODE_STRING Name; + WCHAR NameBuffer[0]; +} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION; + +#define ObjectNameInformation 1 + +#else #include +#endif static void detect_msys_tty(int fd) { @@@ -608,7 -599,7 +608,7 @@@ int winansi_isatty(int fd void winansi_init(void) { int con1, con2; - char name[32]; + wchar_t name[32]; /* check if either stdout or stderr is a console output screen buffer */ con1 = is_console(1); @@@ -628,13 -619,15 +628,15 @@@ } /* create a named pipe to communicate with the console thread */ - xsnprintf(name, sizeof(name), "\\\\.\\pipe\\winansi%lu", GetCurrentProcessId()); - hwrite = CreateNamedPipe(name, PIPE_ACCESS_OUTBOUND, + if (swprintf(name, ARRAY_SIZE(name) - 1, L"\\\\.\\pipe\\winansi%lu", + GetCurrentProcessId()) < 0) + die("Could not initialize winansi pipe name"); + hwrite = CreateNamedPipeW(name, PIPE_ACCESS_OUTBOUND, PIPE_TYPE_BYTE | PIPE_WAIT, 1, BUFFER_SIZE, 0, 0, NULL); if (hwrite == INVALID_HANDLE_VALUE) die_lasterr("CreateNamedPipe failed"); - hread = CreateFile(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + hread = CreateFileW(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); if (hread == INVALID_HANDLE_VALUE) die_lasterr("CreateFile for named pipe failed");