]> granicus.if.org Git - php/commitdiff
Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle exceptions properl...
authorDmitry Stogov <dmitry@zend.com>
Mon, 25 Mar 2013 11:07:27 +0000 (15:07 +0400)
committerDmitry Stogov <dmitry@zend.com>
Mon, 25 Mar 2013 11:07:27 +0000 (15:07 +0400)
NEWS
Zend/zend_vm_def.h
Zend/zend_vm_execute.h

diff --git a/NEWS b/NEWS
index d62e1a189dfa06ae7ce309ab0ab015a31e1aec60..9d5fc6d760ebf5e2098a0314f6ae351508a0bd0b 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -5,6 +5,8 @@ PHP                                                                        NEWS
 - Core
   . Fixed bug #64370 (microtime(true) less than $_SERVER['REQUEST_TIME_FLOAT']).
     (Anatol)
+  . Fixed bug #63914 (zend_do_fcall_common_helper_SPEC does not handle
+    exceptions properly). (Jeff Welch)
   . Fixed bug #62343 (Show class_alias In get_declared_classes()) (Dmitry)
 
 - PCRE:
index e8d3250d0d930abcda28712573e41dcee3b2c0d5..eed924518eface65653f1e3f6417848eda29f6d4 100644 (file)
@@ -2301,10 +2301,6 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
        EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
 
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
-               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
-               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-               EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
-
                if (EX(function_state).function->common.arg_info) {
                        zend_uint i=0;
                        zval **p = (zval**)EX(function_state).arguments;
@@ -2315,15 +2311,22 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY)
                                arg_count--;
                        }
                }
-               if (!zend_execute_internal) {
-                       /* saves one function call if zend_execute_internal is not used */
-                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
-               } else {
-                       zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
-               }
 
-               if (!RETURN_VALUE_USED(opline)) {
-                       zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
+               if (EXPECTED(EG(exception) == NULL)) {
+                       ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                       EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
+
+                       if (!zend_execute_internal) {
+                               /* saves one function call if zend_execute_internal is not used */
+                               ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
+                       } else {
+                               zend_execute_internal(EXECUTE_DATA, RETURN_VALUE_USED(opline) TSRMLS_CC);
+                       }
+
+                       if (!RETURN_VALUE_USED(opline)) {
+                               zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
+                       }
                }
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
                EX(original_return_value) = EG(return_value_ptr_ptr);
index f5cedd872f41753280326ecf88a0345ac61b6594..6edc91a7424d5239d39d7de8ce651e1bc5acd738 100644 (file)
@@ -301,10 +301,6 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
        EX(function_state).arguments = zend_vm_stack_push_args(opline->extended_value TSRMLS_CC);
 
        if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION) {
-               ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
-               EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
-               EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
-
                if (EX(function_state).function->common.arg_info) {
                        zend_uint i=0;
                        zval **p = (zval**)EX(function_state).arguments;
@@ -315,15 +311,22 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR
                                arg_count--;
                        }
                }
-               if (!zend_execute_internal) {
-                       /* saves one function call if zend_execute_internal is not used */
-                       ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
-               } else {
-                       zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
-               }
 
-               if (!RETURN_VALUE_USED(opline)) {
-                       zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
+               if (EXPECTED(EG(exception) == NULL)) {
+                       ALLOC_INIT_ZVAL(EX_T(opline->result.u.var).var.ptr);
+                       EX_T(opline->result.u.var).var.ptr_ptr = &EX_T(opline->result.u.var).var.ptr;
+                       EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference;
+
+                       if (!zend_execute_internal) {
+                               /* saves one function call if zend_execute_internal is not used */
+                               ((zend_internal_function *) EX(function_state).function)->handler(opline->extended_value, EX_T(opline->result.u.var).var.ptr, EX(function_state).function->common.return_reference?&EX_T(opline->result.u.var).var.ptr:NULL, EX(object), RETURN_VALUE_USED(opline) TSRMLS_CC);
+                       } else {
+                               zend_execute_internal(execute_data, RETURN_VALUE_USED(opline) TSRMLS_CC);
+                       }
+
+                       if (!RETURN_VALUE_USED(opline)) {
+                               zval_ptr_dtor(&EX_T(opline->result.u.var).var.ptr);
+                       }
                }
        } else if (EX(function_state).function->type == ZEND_USER_FUNCTION) {
                EX(original_return_value) = EG(return_value_ptr_ptr);