From 0787c5f24910316411e23ee7552df306f422f0e8 Mon Sep 17 00:00:00 2001 From: ducktype Date: Wed, 14 Jun 2017 23:39:53 +0200 Subject: [PATCH 1/7] error_reporting admin_value should not be bypassed by user level This commit reverts the implementation of error_reporting() to the code used in PHP 5.x. The removed code from the PHP 7.x implementation does not seem to add any functionality but miss the checks required to avoid PHP user code to bypass admin_values. Also most of the code php 7.x implementation code is a duplication of zend_alter_ini_entry() and just php 5.x use it directly. https://bugs.php.net/bug.php?id=71340 --- Zend/zend_builtin_functions.c | 46 ++++++----------------------------- 1 file changed, 7 insertions(+), 39 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 000348d4754f3..c88cf09a20e83 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -662,49 +662,17 @@ ZEND_FUNCTION(each) Return the current error_reporting level, and if an argument was passed - change to the new level */ ZEND_FUNCTION(error_reporting) { - zval *err = NULL; + char *err; + int err_len; int old_error_reporting; - ZEND_PARSE_PARAMETERS_START(0, 1) - Z_PARAM_OPTIONAL - Z_PARAM_ZVAL(err) - ZEND_PARSE_PARAMETERS_END(); + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) { + return; + } old_error_reporting = EG(error_reporting); - if (ZEND_NUM_ARGS() != 0) { - zend_string *new_val = zval_get_string(err); - do { - zend_ini_entry *p = EG(error_reporting_ini_entry); - - if (!p) { - p = zend_hash_find_ptr(EG(ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING)); - if (p) { - EG(error_reporting_ini_entry) = p; - } else { - break; - } - } - if (!p->modified) { - if (!EG(modified_ini_directives)) { - ALLOC_HASHTABLE(EG(modified_ini_directives)); - zend_hash_init(EG(modified_ini_directives), 8, NULL, NULL, 0); - } - if (EXPECTED(zend_hash_add_ptr(EG(modified_ini_directives), ZSTR_KNOWN(ZEND_STR_ERROR_REPORTING), p) != NULL)) { - p->orig_value = p->value; - p->orig_modifiable = p->modifiable; - p->modified = 1; - } - } else if (p->orig_value != p->value) { - zend_string_release(p->value); - } - - p->value = new_val; - if (Z_TYPE_P(err) == IS_LONG) { - EG(error_reporting) = Z_LVAL_P(err); - } else { - EG(error_reporting) = atoi(ZSTR_VAL(p->value)); - } - } while (0); + if(ZEND_NUM_ARGS() != 0) { + zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); } RETVAL_LONG(old_error_reporting); From f6d073c08147e133a393259fa895b2288c56711c Mon Sep 17 00:00:00 2001 From: ducktype Date: Thu, 15 Jun 2017 00:53:39 +0200 Subject: [PATCH 2/7] WIN32: Enable graceful termination of child processes emulating ctrl+c via SIGUSR1 in proc_close() Changes to proc_open() and proc_close() to allow graceful termination of child processes (if they handle ctrl+c console event) on WIN32 platform. --- ext/standard/proc_open.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 6d048091c5a4c..3835188d30954 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -258,10 +258,26 @@ PHP_FUNCTION(proc_terminate) } #ifdef PHP_WIN32 - if (TerminateProcess(proc->childHandle, 255)) { - RETURN_TRUE; + // Special WIN32 handling with SIGUSER1 and SIGUSR2 to keep BC + // fallback to TerminateProcess() + if(sig_no == SIGUSR1) { + if (GenerateConsoleCtrlEvent(CTRL_C_EVENT, proc->child)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } + } else if(sig_no == SIGUSR1) { + if (GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, proc->child)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } } else { - RETURN_FALSE; + if (TerminateProcess(proc->childHandle, 255)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } } #else if (kill(proc->child, sig_no) == 0) { @@ -734,6 +750,11 @@ PHP_FUNCTION(proc_open) goto exit_fail; } + //alloc a new console for the child process to allow sending ctrl+c to this specific process and descendants + //the process group id required by GenerateConsoleCtrlEvent() is the same as process id returned by CreateProcessW() + //pi->dwProcessId + dwCreateFlags |= CREATE_NEW_CONSOLE; + if (bypass_shell) { newprocok = CreateProcessW(NULL, cmdw, &security, &security, TRUE, dwCreateFlags, envpw, cwdw, &si, &pi); } else { From bb7fc00714143455ed2b785ad5d2d4f00cc794f1 Mon Sep 17 00:00:00 2001 From: ducktype Date: Thu, 15 Jun 2017 01:10:24 +0200 Subject: [PATCH 3/7] Adapted php 5.x zend_alter_ini_entry() to php 7.x it wasn't building at all! --- Zend/zend_builtin_functions.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index c88cf09a20e83..043591073c36b 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -662,17 +662,20 @@ ZEND_FUNCTION(each) Return the current error_reporting level, and if an argument was passed - change to the new level */ ZEND_FUNCTION(error_reporting) { - char *err; - int err_len; + zval *err = NULL; int old_error_reporting; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &err, &err_len) == FAILURE) { - return; - } + ZEND_PARSE_PARAMETERS_START(0, 1) + Z_PARAM_OPTIONAL + Z_PARAM_ZVAL(err) + ZEND_PARSE_PARAMETERS_END(); old_error_reporting = EG(error_reporting); if(ZEND_NUM_ARGS() != 0) { - zend_alter_ini_entry("error_reporting", sizeof("error_reporting"), err, err_len, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); + zend_string *new_val = zval_get_string(err); + ini_name = zend_string_init("error_reporting", sizeof("error_reporting") - 1, 0); + zend_alter_ini_entry(ini_name, new_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME): + zend_string_release(ini_name); } RETVAL_LONG(old_error_reporting); From 017204b641b4043d837e422677d7bed7ebc9f5f2 Mon Sep 17 00:00:00 2001 From: ducktype Date: Thu, 15 Jun 2017 01:32:13 +0200 Subject: [PATCH 4/7] Fix other errors, i don't ha ve a local build machine to catch this kind of errors before committing! --- Zend/zend_builtin_functions.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 043591073c36b..57aa7fc4280b0 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -673,8 +673,9 @@ ZEND_FUNCTION(error_reporting) old_error_reporting = EG(error_reporting); if(ZEND_NUM_ARGS() != 0) { zend_string *new_val = zval_get_string(err); + zend_string *ini_name; ini_name = zend_string_init("error_reporting", sizeof("error_reporting") - 1, 0); - zend_alter_ini_entry(ini_name, new_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME): + zend_alter_ini_entry(ini_name, new_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); zend_string_release(ini_name); } From 0b34306c365cdb1abd5e46979a261a2e90d00e80 Mon Sep 17 00:00:00 2001 From: ducktype Date: Thu, 15 Jun 2017 01:56:04 +0200 Subject: [PATCH 5/7] Undefined constants! (again no local build to catch this things early) --- Zend/zend_builtin_functions.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index 57aa7fc4280b0..cba77f0f71131 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -29,6 +29,8 @@ #include "zend_closures.h" #include "zend_generators.h" +#include "main/php_ini.h" + static ZEND_FUNCTION(zend_version); static ZEND_FUNCTION(func_num_args); static ZEND_FUNCTION(func_get_arg); From aea154a0a857f63c5d3fa004637171d505e2e969 Mon Sep 17 00:00:00 2001 From: ducktype Date: Thu, 15 Jun 2017 02:14:05 +0200 Subject: [PATCH 6/7] Aagain no local build to catch this things early! --- Zend/zend_builtin_functions.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index cba77f0f71131..707a84f9198d1 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -29,8 +29,6 @@ #include "zend_closures.h" #include "zend_generators.h" -#include "main/php_ini.h" - static ZEND_FUNCTION(zend_version); static ZEND_FUNCTION(func_num_args); static ZEND_FUNCTION(func_get_arg); @@ -677,7 +675,7 @@ ZEND_FUNCTION(error_reporting) zend_string *new_val = zval_get_string(err); zend_string *ini_name; ini_name = zend_string_init("error_reporting", sizeof("error_reporting") - 1, 0); - zend_alter_ini_entry(ini_name, new_val, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); + zend_alter_ini_entry(ini_name, new_val, ZEND_INI_USER, ZEND_INI_STAGE_RUNTIME); zend_string_release(ini_name); } From 9601e75fc1956d5a5941bd56a4314ff987c9cfa5 Mon Sep 17 00:00:00 2001 From: ducktype Date: Fri, 1 Dec 2017 15:12:59 +0100 Subject: [PATCH 7/7] Update .appveyor.yml --- .appveyor.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.appveyor.yml b/.appveyor.yml index 68f1bdf86a5e3..d9bb802b75e0f 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -20,6 +20,12 @@ cache: - c:\build-cache - c:\build-cache\sdk -> .appveyor.yml +init: + - ps: iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + +on_finish: + - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + environment: PHP_BUILD_CACHE_BASE_DIR: c:\build-cache PHP_BUILD_OBJ_DIR: c:\obj