]> granicus.if.org Git - php/commitdiff
Fixed bug #61273 (call_user_func_array with more than 16333 arguments leaks / crashes)
authorXinchen Hui <laruence@php.net>
Sun, 11 Mar 2012 15:28:31 +0000 (15:28 +0000)
committerXinchen Hui <laruence@php.net>
Sun, 11 Mar 2012 15:28:31 +0000 (15:28 +0000)
NEWS
Zend/tests/bug61273.phpt [new file with mode: 0644]
Zend/zend_execute_API.c

diff --git a/NEWS b/NEWS
index c585895392ad3253f41cf9303f2713d0e9ae8b36..6ff05dbe2a2f9d87a5611baef15a7a103ac94b37 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -8,6 +8,8 @@ PHP                                                                        NEWS
   . "Connection: close" instead of "Connection: closed" (Gustavo)
 
 - Core:
+  . Fixed bug #61273 (call_user_func_array with more than 16333 arguments 
+    leaks / crashes). (Laruence)
   . Fixed bug #61225 (Incorect lexing of 0b00*+<NUM>). (Pierrick)
   . Fixed bug #61165 (Segfault - strip_tags()). (Laruence)
   . Fixed bug #61106 (Segfault when using header_register_callback). (Nikita
diff --git a/Zend/tests/bug61273.phpt b/Zend/tests/bug61273.phpt
new file mode 100644 (file)
index 0000000..9d78b27
--- /dev/null
@@ -0,0 +1,15 @@
+--TEST--
+Bug #61273 (call_user_func_array with more than 16333 arguments leaks / crashes)
+--FILE--
+<?php
+/**
+ * for 5.3 #define ZEND_VM_STACK_PAGE_SIZE ((64 * 1024) - 64)
+ * for 5.4 #define ZEND_VM_STACK_PAGE_SIZE ((16 * 1024) - 16)
+ * we should trick EG(argument_stack) into growing
+ */
+$args = array_fill(0, 64 * 1024 - 64, "*");
+call_user_func_array(function(&$a) {}, $args);
+echo strval("okey");
+--EXPECTF--
+Warning: Parameter 1 to {closure}() expected to be a reference, value given in %sbug61273.php on line %d
+okey
index 10adfb6a26e808b50b69425b24d2a2e521e50f0e..1deee2a86c89e4508ce5a5c3d9b7d614415aab28 100644 (file)
@@ -859,7 +859,7 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS
 
                                if (fci->no_separation &&
                                    !ARG_MAY_BE_SENT_BY_REF(EX(function_state).function, i + 1)) {
-                                       if(i) {
+                                       if (i || UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (EG(argument_stack)->top))) {
                                                /* hack to clean up the stack */
                                                zend_vm_stack_push_nocheck((void *) (zend_uintptr_t)i TSRMLS_CC);
                                                zend_vm_stack_clear_multiple(TSRMLS_C);