vendor : apply patches for subprocess.h (#26606)
This commit is contained in:
+107
@@ -0,0 +1,107 @@
|
||||
Fix Windows command line quoting of backslash runs: a trailing backslash, or
|
||||
backslashes preceding a double quote, were not doubled, so CommandLineToArgvW
|
||||
in the child parsed them as escapes and mangled the argument list.
|
||||
|
||||
Upstream PR: https://github.com/sheredom/subprocess.h/pull/101
|
||||
Applied locally by scripts/sync_vendor.py until it is merged upstream.
|
||||
|
||||
(the test/ changes from the PR are omitted, we only vendor subprocess.h)
|
||||
|
||||
diff --git a/subprocess.h b/subprocess.h
|
||||
index 5e80902..b06ad4d 100644
|
||||
--- a/subprocess.h
|
||||
+++ b/subprocess.h
|
||||
@@ -653,6 +653,7 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
int wide_len;
|
||||
int i, j;
|
||||
int need_quoting;
|
||||
+ subprocess_size_t bs_run;
|
||||
unsigned long flags = 0;
|
||||
unsigned long last_error = 0;
|
||||
int result = subprocess_error_unknown;
|
||||
@@ -906,25 +907,29 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
len++;
|
||||
|
||||
// Quote the argument if it has a space in it
|
||||
- if (strpbrk(commandLine[i], "\t\v ") != SUBPROCESS_NULL ||
|
||||
- commandLine[i][0] == SUBPROCESS_NULL)
|
||||
+ need_quoting = strpbrk(commandLine[i], "\t\v ") != SUBPROCESS_NULL ||
|
||||
+ commandLine[i][0] == SUBPROCESS_NULL;
|
||||
+ if (need_quoting)
|
||||
len += 2;
|
||||
|
||||
+ bs_run = 0;
|
||||
for (j = 0; '\0' != commandLine[i][j]; j++) {
|
||||
- switch (commandLine[i][j]) {
|
||||
- default:
|
||||
- break;
|
||||
- case '\\':
|
||||
- if (commandLine[i][j + 1] == '"') {
|
||||
- len++;
|
||||
- }
|
||||
+ len++;
|
||||
|
||||
- break;
|
||||
- case '"':
|
||||
- len++;
|
||||
- break;
|
||||
+ if ('\\' == commandLine[i][j]) {
|
||||
+ bs_run++;
|
||||
+ } else {
|
||||
+ if ('"' == commandLine[i][j]) {
|
||||
+ // Duplicate the preceding run and escape the quote.
|
||||
+ len += bs_run + 1;
|
||||
+ }
|
||||
+ bs_run = 0;
|
||||
}
|
||||
- len++;
|
||||
+ }
|
||||
+
|
||||
+ if (need_quoting) {
|
||||
+ // Duplicate trailing slashes before the generated closing quote.
|
||||
+ len += bs_run;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -949,22 +954,29 @@ int subprocess_create_ex(const char *const commandLine[], int options,
|
||||
commandLineCombined[len++] = '"';
|
||||
}
|
||||
|
||||
- for (j = 0; '\0' != commandLine[i][j]; j++) {
|
||||
- switch (commandLine[i][j]) {
|
||||
- default:
|
||||
- break;
|
||||
- case '\\':
|
||||
- if (commandLine[i][j + 1] == '"') {
|
||||
- commandLineCombined[len++] = '\\';
|
||||
- }
|
||||
+ for (j = 0; '\0' != commandLine[i][j];) {
|
||||
+ bs_run = 0;
|
||||
+ while ('\\' == commandLine[i][j]) {
|
||||
+ bs_run++;
|
||||
+ j++;
|
||||
+ }
|
||||
+
|
||||
+ if ('"' == commandLine[i][j]) {
|
||||
+ // 2n + 1 slashes preserve n slashes and escape the quote.
|
||||
+ bs_run = (bs_run * 2) + 1;
|
||||
+ } else if ('\0' == commandLine[i][j] && need_quoting) {
|
||||
+ // 2n slashes preserve n slashes before the closing quote.
|
||||
+ bs_run *= 2;
|
||||
+ }
|
||||
|
||||
- break;
|
||||
- case '"':
|
||||
+ while (bs_run > 0) {
|
||||
commandLineCombined[len++] = '\\';
|
||||
- break;
|
||||
+ bs_run--;
|
||||
}
|
||||
|
||||
- commandLineCombined[len++] = commandLine[i][j];
|
||||
+ if ('\0' != commandLine[i][j]) {
|
||||
+ commandLineCombined[len++] = commandLine[i][j++];
|
||||
+ }
|
||||
}
|
||||
if (need_quoting) {
|
||||
commandLineCombined[len++] = '"';
|
||||
Reference in New Issue
Block a user