Skip to content

Commit 9ca449e

Browse files
committed
Make quoting of cmd execution functions consistent
While the `$command` passed to `proc_open()` had to be wrapped in double-quotes manually, that was implicitly done for all other program execution functions. This could easily introduce bugs and even security issues when switching from one to another program execution function. Furthermore we ensure that the additional quotes are always unwrapped regardless of what is passed as `$command` by passing the `/s` flag to cmd.exe. As it was, `shell_exec('path with spaces/program.exe')` did execute program.exe, but adding an argument (`shell_exec('path with spaces/program.exe -h)`) failed to execute program.exe, because cmd.exe stripped the additional quotes. While these changes obviously can cause BC breaks, we feel that in the long run the benefits of having consistent behavior for all program execution functions outweighs the drawbacks of potentially breaking some code now.
1 parent 72737b0 commit 9ca449e

File tree

4 files changed

+10
-4
lines changed

4 files changed

+10
-4
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ PHP NEWS
108108
filter). (kkopachev)
109109
. Fixed bug #78385 (parse_url() does not include 'query' when question mark
110110
is the last char). (Islam Israfilov)
111+
. Made quoting of cmd execution functions consistent. (cmb)
111112

112113
- tidy:
113114
. Removed the unused $use_include_path parameter from tidy_repair_string().

TSRM/tsrm_win32.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -478,12 +478,12 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd,
478478
return NULL;
479479
}
480480

481-
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2);
481+
cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /s /c ")+2);
482482
if (!cmd) {
483483
return NULL;
484484
}
485485

486-
sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command);
486+
sprintf(cmd, "%s /s /c \"%s\"", TWG(comspec), command);
487487
cmdw = php_win32_cp_any_to_w(cmd);
488488
if (!cmdw) {
489489
free(cmd);

UPGRADING

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,11 @@ PHP 8.0 UPGRADE NOTES
472472
12. Windows Support
473473
========================================
474474

475+
- Standard:
476+
. Program execution functions (proc_open(), exec(), popen() etc.) using the
477+
shell now consistently execute `%comspec% /s /c "$commandline"`, which has
478+
the same effect as executing `$commandline` (without additional quotes).
479+
475480
- php-test-pack:
476481
. The test runner has been renamed from run-test.php to run-tests.php, to
477482
match its name in php-src.

ext/standard/proc_open.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -953,13 +953,13 @@ PHP_FUNCTION(proc_open)
953953
wchar_t *cmdw2;
954954

955955

956-
len = (sizeof(COMSPEC_NT) + sizeof(" /c ") + tmp_len + 1);
956+
len = (sizeof(COMSPEC_NT) + sizeof(" /s /c ") + tmp_len + 3);
957957
cmdw2 = (wchar_t *)malloc(len * sizeof(wchar_t));
958958
if (!cmdw2) {
959959
php_error_docref(NULL, E_WARNING, "Command conversion failed");
960960
goto exit_fail;
961961
}
962-
ret = _snwprintf(cmdw2, len, L"%hs /c %s", COMSPEC_NT, cmdw);
962+
ret = _snwprintf(cmdw2, len, L"%hs /s /c \"%s\"", COMSPEC_NT, cmdw);
963963

964964
if (-1 == ret) {
965965
free(cmdw2);

0 commit comments

Comments
 (0)