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 {
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.