diff options
author | Vincent Ambo <tazjin@google.com> | 2020-05-25T23·06+0100 |
---|---|---|
committer | Vincent Ambo <tazjin@google.com> | 2020-05-25T23·06+0100 |
commit | 93ba78d6f4632ef1c5228965e3edc8c0faf88c1e (patch) | |
tree | 85730c182a9f5f492ade8e8ccdb1c2356f9900bd /third_party/git/compat/mingw.c | |
parent | 6f8fbf4aa4b1654ab27d4829e114538761817de0 (diff) |
revert(3p/git): Revert merge of git upstream at v2.26.2 r/852
This causes cgit to serve error pages, which is undesirable. This reverts commit 5229c9b232de5bfa959ad6ebbb4c8192ac513352, reversing changes made to f2b211131f2347342dde63975b09cf603149f1a3.
Diffstat (limited to 'third_party/git/compat/mingw.c')
-rw-r--r-- | third_party/git/compat/mingw.c | 409 |
1 files changed, 51 insertions, 358 deletions
diff --git a/third_party/git/compat/mingw.c b/third_party/git/compat/mingw.c index d14065d60ec4..738f0a826a51 100644 --- a/third_party/git/compat/mingw.c +++ b/third_party/git/compat/mingw.c @@ -13,19 +13,6 @@ static const int delay[] = { 0, 1, 10, 20, 40 }; -void open_in_gdb(void) -{ - static struct child_process cp = CHILD_PROCESS_INIT; - extern char *_pgmptr; - - argv_array_pushl(&cp.args, "mintty", "gdb", NULL); - argv_array_pushf(&cp.args, "--pid=%d", getpid()); - cp.clean_on_exit = 1; - if (start_command(&cp) < 0) - die_errno("Could not start gdb"); - sleep(1); -} - int err_win_to_posix(DWORD winerr) { int error = ENOSYS; @@ -127,7 +114,6 @@ int err_win_to_posix(DWORD winerr) case ERROR_SHARING_BUFFER_EXCEEDED: error = ENFILE; break; case ERROR_SHARING_VIOLATION: error = EACCES; break; case ERROR_STACK_OVERFLOW: error = ENOMEM; break; - case ERROR_SUCCESS: BUG("err_win_to_posix() called without an error!"); case ERROR_SWAPERROR: error = ENOENT; break; case ERROR_TOO_MANY_MODULES: error = EMFILE; break; case ERROR_TOO_MANY_OPEN_FILES: error = EMFILE; break; @@ -226,7 +212,6 @@ enum hide_dotfiles_type { HIDE_DOTFILES_DOTGITONLY }; -static int core_restrict_inherited_handles = -1; static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; static char *unset_environment_variables; @@ -246,15 +231,6 @@ int mingw_core_config(const char *var, const char *value, void *cb) return 0; } - if (!strcmp(var, "core.restrictinheritedhandles")) { - if (value && !strcasecmp(value, "auto")) - core_restrict_inherited_handles = -1; - else - core_restrict_inherited_handles = - git_config_bool(var, value); - return 0; - } - return 0; } @@ -387,8 +363,6 @@ static inline int needs_hiding(const char *path) /* ignore trailing slashes */ if (*path) basename = path; - else - break; } if (hide_dotfiles == HIDE_DOTFILES_TRUE) @@ -416,12 +390,6 @@ int mingw_mkdir(const char *path, int mode) { int ret; wchar_t wpath[MAX_PATH]; - - if (!is_valid_win32_path(path, 0)) { - errno = EINVAL; - return -1; - } - if (xutftowcs_path(wpath, path) < 0) return -1; ret = _wmkdir(wpath); @@ -495,7 +463,7 @@ int mingw_open (const char *filename, int oflags, ...) typedef int (*open_fn_t)(wchar_t const *wfilename, int oflags, ...); va_list args; unsigned mode; - int fd, create = (oflags & (O_CREAT | O_EXCL)) == (O_CREAT | O_EXCL); + int fd; wchar_t wfilename[MAX_PATH]; open_fn_t open_fn; @@ -503,21 +471,16 @@ int mingw_open (const char *filename, int oflags, ...) mode = va_arg(args, int); va_end(args); - if (!is_valid_win32_path(filename, !create)) { - errno = create ? EINVAL : ENOENT; - return -1; - } + if (filename && !strcmp(filename, "/dev/null")) + filename = "nul"; if ((oflags & O_APPEND) && !is_local_named_pipe_path(filename)) open_fn = mingw_open_append; else open_fn = _wopen; - if (filename && !strcmp(filename, "/dev/null")) - wcscpy(wfilename, L"nul"); - else if (xutftowcs_path(wfilename, filename) < 0) + if (xutftowcs_path(wfilename, filename) < 0) return -1; - fd = open_fn(wfilename, oflags, mode); if (fd < 0 && (oflags & O_ACCMODE) != O_RDONLY && errno == EACCES) { @@ -575,17 +538,10 @@ FILE *mingw_fopen (const char *filename, const char *otype) FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; if (filename && !strcmp(filename, "/dev/null")) - wcscpy(wfilename, L"nul"); - else if (!is_valid_win32_path(filename, 1)) { - int create = otype && strchr(otype, 'w'); - errno = create ? EINVAL : ENOENT; - return NULL; - } else if (xutftowcs_path(wfilename, filename) < 0) - return NULL; - - if (xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) + filename = "nul"; + if (xutftowcs_path(wfilename, filename) < 0 || + xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; - if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { error("could not unhide %s", filename); return NULL; @@ -604,17 +560,10 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; if (filename && !strcmp(filename, "/dev/null")) - wcscpy(wfilename, L"nul"); - else if (!is_valid_win32_path(filename, 1)) { - int create = otype && strchr(otype, 'w'); - errno = create ? EINVAL : ENOENT; - return NULL; - } else if (xutftowcs_path(wfilename, filename) < 0) - return NULL; - - if (xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) + filename = "nul"; + if (xutftowcs_path(wfilename, filename) < 0 || + xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; - if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { error("could not unhide %s", filename); return NULL; @@ -1035,16 +984,16 @@ int pipe(int filedes[2]) struct tm *gmtime_r(const time_t *timep, struct tm *result) { - if (gmtime_s(result, timep) == 0) - return result; - return NULL; + /* gmtime() in MSVCRT.DLL is thread-safe, but not reentrant */ + memcpy(result, gmtime(timep), sizeof(struct tm)); + return result; } struct tm *localtime_r(const time_t *timep, struct tm *result) { - if (localtime_s(result, timep) == 0) - return result; - return NULL; + /* localtime() in MSVCRT.DLL is thread-safe, but not reentrant */ + memcpy(result, localtime(timep), sizeof(struct tm)); + return result; } char *mingw_getcwd(char *pointer, int len) @@ -1103,7 +1052,7 @@ static const char *quote_arg_msvc(const char *arg) p++; len++; } - if (*p == '"' || !*p) + if (*p == '"') n += count*2 + 1; continue; } @@ -1125,19 +1074,16 @@ static const char *quote_arg_msvc(const char *arg) count++; *d++ = *arg++; } - if (*arg == '"' || !*arg) { + if (*arg == '"') { while (count-- > 0) *d++ = '\\'; - /* don't escape the surrounding end quote */ - if (!*arg) - break; *d++ = '\\'; } } *d++ = *arg++; } *d++ = '"'; - *d++ = '\0'; + *d++ = 0; return q; } @@ -1150,14 +1096,13 @@ static const char *quote_arg_msys2(const char *arg) for (p = arg; *p; p++) { int ws = isspace(*p); - if (!ws && *p != '\\' && *p != '"' && *p != '{' && *p != '\'' && - *p != '?' && *p != '*' && *p != '~') + if (!ws && *p != '\\' && *p != '"' && *p != '{') continue; if (!buf.len) strbuf_addch(&buf, '"'); if (p != p2) strbuf_add(&buf, p2, p - p2); - if (*p == '\\' || *p == '"') + if (!ws && *p != '{') strbuf_addch(&buf, '\\'); p2 = p; } @@ -1167,7 +1112,7 @@ static const char *quote_arg_msys2(const char *arg) else if (!buf.len) return arg; else - strbuf_add(&buf, p2, p - p2); + strbuf_add(&buf, p2, p - p2), strbuf_addch(&buf, '"'); return strbuf_detach(&buf, 0); @@ -1216,21 +1161,14 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd, int isexe, int exe_only) { char path[MAX_PATH]; - wchar_t wpath[MAX_PATH]; snprintf(path, sizeof(path), "%.*s\\%s.exe", dirlen, dir, cmd); - if (xutftowcs_path(wpath, path) < 0) - return NULL; - - if (!isexe && _waccess(wpath, F_OK) == 0) + if (!isexe && access(path, F_OK) == 0) return xstrdup(path); - wpath[wcslen(wpath)-4] = '\0'; - if ((!exe_only || isexe) && _waccess(wpath, F_OK) == 0) { - if (!(GetFileAttributesW(wpath) & FILE_ATTRIBUTE_DIRECTORY)) { - path[strlen(path)-4] = '\0'; + path[strlen(path)-4] = '\0'; + if ((!exe_only || isexe) && access(path, F_OK) == 0) + if (!(GetFileAttributes(path) & FILE_ATTRIBUTE_DIRECTORY)) return xstrdup(path); - } - } return NULL; } @@ -1245,7 +1183,7 @@ static char *path_lookup(const char *cmd, int exe_only) int len = strlen(cmd); int isexe = len >= 4 && !strcasecmp(cmd+len-4, ".exe"); - if (strpbrk(cmd, "/\\")) + if (strchr(cmd, '/') || strchr(cmd, '\\')) return xstrdup(cmd); path = mingw_getenv("PATH"); @@ -1291,6 +1229,11 @@ static int wenvcmp(const void *a, const void *b) return _wcsnicmp(p, q, p_len); } +/* We need a stable sort to convert the environment between UTF-16 <-> UTF-8 */ +#ifndef INTERNAL_QSORT +#include "qsort.c" +#endif + /* * Build an environment block combining the inherited environment * merged with the given list of settings. @@ -1322,15 +1265,15 @@ static wchar_t *make_environment_block(char **deltaenv) } ALLOC_ARRAY(result, size); - COPY_ARRAY(result, wenv, size); + memcpy(result, wenv, size * sizeof(*wenv)); FreeEnvironmentStringsW(wenv); return result; } /* * If there is a deltaenv, let's accumulate all keys into `array`, - * sort them using the stable git_stable_qsort() and then copy, - * skipping duplicate keys + * sort them using the stable git_qsort() and then copy, skipping + * duplicate keys */ for (p = wenv; p && *p; ) { ALLOC_GROW(array, nr + 1, alloc); @@ -1353,7 +1296,7 @@ static wchar_t *make_environment_block(char **deltaenv) p += wlen + 1; } - git_stable_qsort(array, nr, sizeof(*array), wenvcmp); + git_qsort(array, nr, sizeof(*array), wenvcmp); ALLOC_ARRAY(result, size + delta_size); for (p = result, i = 0; i < nr; i++) { @@ -1366,7 +1309,7 @@ static wchar_t *make_environment_block(char **deltaenv) continue; size = wcslen(array[i]) + 1; - COPY_ARRAY(p, array[i], size); + memcpy(p, array[i], size * sizeof(*p)); p += size; } *p = L'\0'; @@ -1424,10 +1367,7 @@ static inline int match_last_path_component(const char *path, size_t *len, static int is_msys2_sh(const char *cmd) { - if (!cmd) - return 0; - - if (!strcmp(cmd, "sh")) { + if (cmd && !strcmp(cmd, "sh")) { static int ret = -1; char *p; @@ -1447,16 +1387,6 @@ static int is_msys2_sh(const char *cmd) } return ret; } - - if (ends_with(cmd, "\\sh.exe")) { - static char *sh; - - if (!sh) - sh = path_lookup("sh", 0); - - return !fspathcmp(cmd, sh); - } - return 0; } @@ -1464,34 +1394,15 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen const char *dir, int prepend_cmd, int fhin, int fhout, int fherr) { - static int restrict_handle_inheritance = -1; - STARTUPINFOEXW si; + STARTUPINFOW si; PROCESS_INFORMATION pi; - LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL; - HANDLE stdhandles[3]; - DWORD stdhandles_count = 0; - SIZE_T size; struct strbuf args; wchar_t wcmd[MAX_PATH], wdir[MAX_PATH], *wargs, *wenvblk = NULL; unsigned flags = CREATE_UNICODE_ENVIRONMENT; BOOL ret; HANDLE cons; const char *(*quote_arg)(const char *arg) = - is_msys2_sh(cmd ? cmd : *argv) ? - quote_arg_msys2 : quote_arg_msvc; - - /* Make sure to override previous errors, if any */ - errno = 0; - - if (restrict_handle_inheritance < 0) - restrict_handle_inheritance = core_restrict_inherited_handles; - /* - * The following code to restrict which handles are inherited seems - * to work properly only on Windows 7 and later, so let's disable it - * on Windows Vista and 2008. - */ - if (restrict_handle_inheritance < 0) - restrict_handle_inheritance = GetVersion() >> 16 >= 7601; + is_msys2_sh(*argv) ? quote_arg_msys2 : quote_arg_msvc; do_unset_environment_variables(); @@ -1520,23 +1431,11 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen CloseHandle(cons); } memset(&si, 0, sizeof(si)); - si.StartupInfo.cb = sizeof(si); - si.StartupInfo.hStdInput = winansi_get_osfhandle(fhin); - si.StartupInfo.hStdOutput = winansi_get_osfhandle(fhout); - si.StartupInfo.hStdError = winansi_get_osfhandle(fherr); - - /* The list of handles cannot contain duplicates */ - if (si.StartupInfo.hStdInput != INVALID_HANDLE_VALUE) - stdhandles[stdhandles_count++] = si.StartupInfo.hStdInput; - if (si.StartupInfo.hStdOutput != INVALID_HANDLE_VALUE && - si.StartupInfo.hStdOutput != si.StartupInfo.hStdInput) - stdhandles[stdhandles_count++] = si.StartupInfo.hStdOutput; - if (si.StartupInfo.hStdError != INVALID_HANDLE_VALUE && - si.StartupInfo.hStdError != si.StartupInfo.hStdInput && - si.StartupInfo.hStdError != si.StartupInfo.hStdOutput) - stdhandles[stdhandles_count++] = si.StartupInfo.hStdError; - if (stdhandles_count) - si.StartupInfo.dwFlags |= STARTF_USESTDHANDLES; + si.cb = sizeof(si); + si.dwFlags = STARTF_USESTDHANDLES; + si.hStdInput = winansi_get_osfhandle(fhin); + si.hStdOutput = winansi_get_osfhandle(fhout); + si.hStdError = winansi_get_osfhandle(fherr); if (*argv && !strcmp(cmd, *argv)) wcmd[0] = L'\0'; @@ -1569,98 +1468,16 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen wenvblk = make_environment_block(deltaenv); memset(&pi, 0, sizeof(pi)); - if (restrict_handle_inheritance && stdhandles_count && - (InitializeProcThreadAttributeList(NULL, 1, 0, &size) || - GetLastError() == ERROR_INSUFFICIENT_BUFFER) && - (attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST) - (HeapAlloc(GetProcessHeap(), 0, size))) && - InitializeProcThreadAttributeList(attr_list, 1, 0, &size) && - UpdateProcThreadAttribute(attr_list, 0, - PROC_THREAD_ATTRIBUTE_HANDLE_LIST, - stdhandles, - stdhandles_count * sizeof(HANDLE), - NULL, NULL)) { - si.lpAttributeList = attr_list; - flags |= EXTENDED_STARTUPINFO_PRESENT; - } - - ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL, - stdhandles_count ? TRUE : FALSE, - flags, wenvblk, dir ? wdir : NULL, - &si.StartupInfo, &pi); - - /* - * On Windows 2008 R2, it seems that specifying certain types of handles - * (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an - * error. Rather than playing finicky and fragile games, let's just try - * to detect this situation and simply try again without restricting any - * handle inheritance. This is still better than failing to create - * processes. - */ - if (!ret && restrict_handle_inheritance && stdhandles_count) { - DWORD err = GetLastError(); - struct strbuf buf = STRBUF_INIT; - - if (err != ERROR_NO_SYSTEM_RESOURCES && - /* - * On Windows 7 and earlier, handles on pipes and character - * devices are inherited automatically, and cannot be - * specified in the thread handle list. Rather than trying - * to catch each and every corner case (and running the - * chance of *still* forgetting a few), let's just fall - * back to creating the process without trying to limit the - * handle inheritance. - */ - !(err == ERROR_INVALID_PARAMETER && - GetVersion() >> 16 < 9200) && - !getenv("SUPPRESS_HANDLE_INHERITANCE_WARNING")) { - DWORD fl = 0; - int i; - - setenv("SUPPRESS_HANDLE_INHERITANCE_WARNING", "1", 1); - - for (i = 0; i < stdhandles_count; i++) { - HANDLE h = stdhandles[i]; - strbuf_addf(&buf, "handle #%d: %p (type %lx, " - "handle info (%d) %lx\n", i, h, - GetFileType(h), - GetHandleInformation(h, &fl), - fl); - } - strbuf_addstr(&buf, "\nThis is a bug; please report it " - "at\nhttps://github.com/git-for-windows/" - "git/issues/new\n\n" - "To suppress this warning, please set " - "the environment variable\n\n" - "\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1" - "\n"); - } - restrict_handle_inheritance = 0; - flags &= ~EXTENDED_STARTUPINFO_PRESENT; - ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL, - TRUE, flags, wenvblk, dir ? wdir : NULL, - &si.StartupInfo, &pi); - if (!ret) - errno = err_win_to_posix(GetLastError()); - if (ret && buf.len) { - warning("failed to restrict file handles (%ld)\n\n%s", - err, buf.buf); - } - strbuf_release(&buf); - } else if (!ret) - errno = err_win_to_posix(GetLastError()); - - if (si.lpAttributeList) - DeleteProcThreadAttributeList(si.lpAttributeList); - if (attr_list) - HeapFree(GetProcessHeap(), 0, attr_list); + ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL, TRUE, + flags, wenvblk, dir ? wdir : NULL, &si, &pi); free(wenvblk); free(wargs); - if (!ret) + if (!ret) { + errno = ENOENT; return -1; - + } CloseHandle(pi.hThread); /* @@ -1745,7 +1562,7 @@ static int try_shell_exec(const char *cmd, char *const *argv) while (argv[argc]) argc++; ALLOC_ARRAY(argv2, argc + 1); argv2[0] = (char *)cmd; /* full path to the script file */ - COPY_ARRAY(&argv2[1], &argv[1], argc); + memcpy(&argv2[1], &argv[1], sizeof(*argv) * argc); exec_id = trace2_exec(prog, argv2); pid = mingw_spawnv(prog, argv2, 1); if (pid >= 0) { @@ -1846,8 +1663,6 @@ char *mingw_getenv(const char *name) if (!w_key) die("Out of memory, (tried to allocate %u wchar_t's)", len_key); xutftowcs(w_key, name, len_key); - /* GetEnvironmentVariableW() only sets the last error upon failure */ - SetLastError(ERROR_SUCCESS); len_value = GetEnvironmentVariableW(w_key, w_value, ARRAY_SIZE(w_value)); if (!len_value && GetLastError() == ERROR_ENVVAR_NOT_FOUND) { free(w_key); @@ -2546,128 +2361,6 @@ static void setup_windows_environment(void) } } -int is_valid_win32_path(const char *path, int allow_literal_nul) -{ - const char *p = path; - int preceding_space_or_period = 0, i = 0, periods = 0; - - if (!protect_ntfs) - return 1; - - skip_dos_drive_prefix((char **)&path); - goto segment_start; - - for (;;) { - char c = *(path++); - switch (c) { - case '\0': - case '/': case '\\': - /* cannot end in ` ` or `.`, except for `.` and `..` */ - if (preceding_space_or_period && - (i != periods || periods > 2)) - return 0; - if (!c) - return 1; - - i = periods = preceding_space_or_period = 0; - -segment_start: - switch (*path) { - case 'a': case 'A': /* AUX */ - if (((c = path[++i]) != 'u' && c != 'U') || - ((c = path[++i]) != 'x' && c != 'X')) { -not_a_reserved_name: - path += i; - continue; - } - break; - case 'c': case 'C': /* COM<N>, CON, CONIN$, CONOUT$ */ - if ((c = path[++i]) != 'o' && c != 'O') - goto not_a_reserved_name; - c = path[++i]; - if (c == 'm' || c == 'M') { /* COM<N> */ - if (!isdigit(path[++i])) - goto not_a_reserved_name; - } else if (c == 'n' || c == 'N') { /* CON */ - c = path[i + 1]; - if ((c == 'i' || c == 'I') && - ((c = path[i + 2]) == 'n' || - c == 'N') && - path[i + 3] == '$') - i += 3; /* CONIN$ */ - else if ((c == 'o' || c == 'O') && - ((c = path[i + 2]) == 'u' || - c == 'U') && - ((c = path[i + 3]) == 't' || - c == 'T') && - path[i + 4] == '$') - i += 4; /* CONOUT$ */ - } else - goto not_a_reserved_name; - break; - case 'l': case 'L': /* LPT<N> */ - if (((c = path[++i]) != 'p' && c != 'P') || - ((c = path[++i]) != 't' && c != 'T') || - !isdigit(path[++i])) - goto not_a_reserved_name; - break; - case 'n': case 'N': /* NUL */ - if (((c = path[++i]) != 'u' && c != 'U') || - ((c = path[++i]) != 'l' && c != 'L') || - (allow_literal_nul && - !path[i + 1] && p == path)) - goto not_a_reserved_name; - break; - case 'p': case 'P': /* PRN */ - if (((c = path[++i]) != 'r' && c != 'R') || - ((c = path[++i]) != 'n' && c != 'N')) - goto not_a_reserved_name; - break; - default: - continue; - } - - /* - * So far, this looks like a reserved name. Let's see - * whether it actually is one: trailing spaces, a file - * extension, or an NTFS Alternate Data Stream do not - * matter, the name is still reserved if any of those - * follow immediately after the actual name. - */ - i++; - if (path[i] == ' ') { - preceding_space_or_period = 1; - while (path[++i] == ' ') - ; /* skip all spaces */ - } - - c = path[i]; - if (c && c != '.' && c != ':' && c != '/' && c != '\\') - goto not_a_reserved_name; - - /* contains reserved name */ - return 0; - case '.': - periods++; - /* fallthru */ - case ' ': - preceding_space_or_period = 1; - i++; - continue; - case ':': /* DOS drive prefix was already skipped */ - case '<': case '>': case '"': case '|': case '?': case '*': - /* illegal character */ - return 0; - default: - if (c > '\0' && c < '\x20') - /* illegal character */ - return 0; - } - preceding_space_or_period = 0; - i++; - } -} - #if !defined(_MSC_VER) /* * Disable MSVCRT command line wildcard expansion (__getmainargs called from |