com php-src: Fixed bug #74164 (PHP hangs when an invalid value is dynamically passed to typehinted by-ref arg): NEWS Zend/tests/bug74164.phpt Zend/zend_execute_API.c
[email protected] (Xinchen Hui)
| Newsgroups | php.cvs |
|---|---|
| Message-ID | <[email protected]> |
Commit: 36fcc4cb5d92dabc8c8f6f0587c81093bcac878c Author: Xinchen Hui <[email protected]> Sat, 25 Feb 2017 12:00:42 +0800 Parents: d1f36d6d8ebd76b2d1014a1fcccdf75baa70cdb0 Branches: PHP-7.1 master Link: http://git.php.net/?p=php-src.git;a=commitdiff;h=36fcc4cb5d92dabc8c8f6f0587c81093bcac878c Log: Fixed bug #74164 (PHP hangs when an invalid value is dynamically passed to typehinted by-ref arg) Bugs: https://bugs.php.net/74164 Changed paths: M NEWS A Zend/tests/bug74164.phpt M Zend/zend_execute_API.c Diff: diff --git a/NEWS b/NEWS index a2129d9..e5b94aa 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ PHP NEWS ?? ??? 2017, PHP 7.1.3 - Core: + . Fixed bug #74164 (PHP hangs when an invalid value is dynamically passed to + typehinted by-ref arg). (Laruence) . Fixed bug #74093 (Maximum execution time of n+2 seconds exceed not written in error_log). (Laruence) . Fixed bug #73989 (PHP 7.1 Segfaults within Symfony test suite). diff --git a/Zend/tests/bug74164.phpt b/Zend/tests/bug74164.phpt new file mode 100644 index 0000000..354b2f5 --- /dev/null +++ b/Zend/tests/bug74164.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #74164 (PHP hangs when an invalid value is dynamically passed to typehinted by-ref arg) +--FILE-- +<?php + +namespace Foo; + +set_error_handler(function ($type, $msg) { + throw new \Exception($msg); +}); + +call_user_func(function (array &$ref) {var_dump("xxx");}, 'not_an_array_variable'); +?> +--EXPECTF-- +Fatal error: Uncaught Exception: Parameter 1 to Foo\{closure}() expected to be a reference, value given in %sbug74164.php:%d +Stack trace: +#0 [internal function]: Foo\{closure}(%s) +#1 %sbug74164.php(%d): call_user_func(%s) +#2 {main} + thrown in %sbug74164.php on line %d diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index e021985..9080ae5 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -761,6 +761,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / if (fci->object && (!EG(objects_store).object_buckets || !IS_OBJ_VALID(EG(objects_store).object_buckets[fci->object->handle]))) { + zend_vm_stack_free_call_frame(call); if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } @@ -770,6 +771,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / if (func->common.fn_flags & (ZEND_ACC_ABSTRACT|ZEND_ACC_DEPRECATED)) { if (func->common.fn_flags & ZEND_ACC_ABSTRACT) { zend_throw_error(NULL, "Cannot call abstract method %s::%s()", ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name)); + zend_vm_stack_free_call_frame(call); if (EG(current_execute_data) == &dummy_execute_data) { EG(current_execute_data) = dummy_execute_data.prev_execute_data; } @@ -780,6 +782,13 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / func->common.scope ? ZSTR_VAL(func->common.scope->name) : "", func->common.scope ? "::" : "", ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception))) { + zend_vm_stack_free_call_frame(call); + if (EG(current_execute_data) == &dummy_execute_data) { + EG(current_execute_data) = dummy_execute_data.prev_execute_data; + } + return FAILURE; + } } } @@ -800,6 +809,15 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache) / func->common.scope ? ZSTR_VAL(func->common.scope->name) : "", func->common.scope ? "::" : "", ZSTR_VAL(func->common.function_name)); + if (UNEXPECTED(EG(exception))) { + ZEND_CALL_NUM_ARGS(call) = i; + zend_vm_stack_free_args(call); + zend_vm_stack_free_call_frame(call); + if (EG(current_execute_data) == &dummy_execute_data) { + EG(current_execute_data) = dummy_execute_data.prev_execute_data; + } + return FAILURE; + } } } } else {