summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2018-11-02 14:26:24 +0100
committerNikita Popov <nikita.ppv@gmail.com>2018-11-02 14:29:03 +0100
commit4daa413898948dad90bc797ccab200115326efc7 (patch)
tree714547fabfc012ef9437d27a628b2acb78de1fed
parent10255a0cd9af92247c6814c61520ca7c23054100 (diff)
downloadphp-git-4daa413898948dad90bc797ccab200115326efc7.tar.gz
Fixed bug #77092
Weird that this worked for so long, probably because nearly all ext/standard functions use fast ZPP rather than ordinary ZPP.
-rw-r--r--NEWS1
-rw-r--r--ext/opcache/Optimizer/sccp.c6
-rw-r--r--ext/opcache/tests/bug77092.phpt20
3 files changed, 26 insertions, 1 deletions
diff --git a/NEWS b/NEWS
index 677fc21325..bff096b073 100644
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,7 @@ PHP NEWS
- Opcache:
. Fixed bug #77058 (Type inference in opcache causes side effects). (Nikita)
+ . Fixed bug #77092 (array_diff_key() - segmentation fault). (Nikita)
- SOAP:
. Fixed bug #50675 (SoapClient can't handle object references correctly).
diff --git a/ext/opcache/Optimizer/sccp.c b/ext/opcache/Optimizer/sccp.c
index 802587e8e9..a519196e30 100644
--- a/ext/opcache/Optimizer/sccp.c
+++ b/ext/opcache/Optimizer/sccp.c
@@ -585,7 +585,7 @@ static inline int ct_eval_in_array(zval *result, uint32_t extended_value, zval *
static inline int ct_eval_func_call(
zval *result, zend_string *name, uint32_t num_args, zval **args) {
uint32_t i;
- zend_execute_data *execute_data;
+ zend_execute_data *execute_data, *prev_execute_data;
zend_function *func;
int overflow;
@@ -840,6 +840,9 @@ static inline int ct_eval_func_call(
execute_data = safe_emalloc(num_args, sizeof(zval), ZEND_CALL_FRAME_SLOT * sizeof(zval));
memset(execute_data, 0, sizeof(zend_execute_data));
+ prev_execute_data = EG(current_execute_data);
+ EG(current_execute_data) = execute_data;
+
EX(func) = func;
EX_NUM_ARGS() = num_args;
for (i = 0; i < num_args; i++) {
@@ -850,6 +853,7 @@ static inline int ct_eval_func_call(
zval_ptr_dtor_nogc(EX_VAR_NUM(i));
}
efree(execute_data);
+ EG(current_execute_data) = prev_execute_data;
return SUCCESS;
}
diff --git a/ext/opcache/tests/bug77092.phpt b/ext/opcache/tests/bug77092.phpt
new file mode 100644
index 0000000000..9e64c50e77
--- /dev/null
+++ b/ext/opcache/tests/bug77092.phpt
@@ -0,0 +1,20 @@
+--TEST--
+Bug #77092: array_diff_key() - segmentation fault
+--INI--
+opcache.enable_cli=1
+opcache.optimization_level=-1
+--FILE--
+<?php
+function test() {
+ $anyArrayOne = ['foo' => 'bar', 'bar' => 'baz'];
+ $anyArrayTwo = ['foo' => null];
+
+ print_r(array_diff_key($anyArrayOne, $anyArrayTwo));
+}
+test();
+?>
+--EXPECT--
+Array
+(
+ [bar] => baz
+)