diff options
author | Timm Friebe <thekid@thekid.de> | 2014-07-06 14:48:42 +0200 |
---|---|---|
committer | Timm Friebe <thekid@thekid.de> | 2014-07-06 14:48:42 +0200 |
commit | df908275f65dbac0990576db6be0534433f72c0d (patch) | |
tree | ecc4cd65839506a58ba0acb02e35a6f5a89aa2b1 | |
parent | ab4ded90f2e4ace3b90098cf1eea79d977255648 (diff) | |
download | php-git-df908275f65dbac0990576db6be0534433f72c0d.tar.gz |
Handle ZEND_EXT_FCALL_END, skipping if necessary
Verified with running tests with new "-e" run-tests arg:
$ make test TESTS=Zend/tests/*-on-non-objects-*phpt TEST_PHP_ARGS=-e
# Tests passed : 11 (100.0%)
$ make test TESTS=Zend/tests/*-on-non-objects-*phpt
# Tests passed : 11 (100.0%)
Before, this would cause a SEGV. Thanks @nikic for raising this concern
-rw-r--r-- | Zend/tests/methods-on-non-objects-throw.phpt | 4 | ||||
-rw-r--r-- | Zend/zend_vm_def.h | 14 | ||||
-rw-r--r-- | Zend/zend_vm_execute.h | 180 |
3 files changed, 180 insertions, 18 deletions
diff --git a/Zend/tests/methods-on-non-objects-throw.phpt b/Zend/tests/methods-on-non-objects-throw.phpt index 7bbbbf6039..ac27ac3f88 100644 --- a/Zend/tests/methods-on-non-objects-throw.phpt +++ b/Zend/tests/methods-on-non-objects-throw.phpt @@ -3,6 +3,7 @@ Convert errors to exceptions from method calls on non-objects raise recoverable --FILE-- <?php set_error_handler(function($code, $message) { + echo "Raising...\n"; if (0 === strncmp('Call', $message, 4)) { throw new BadMethodCallException($message); } else if (0 === strncmp('Argument', $message, 8)) { @@ -13,6 +14,7 @@ set_error_handler(function($code, $message) { }, E_RECOVERABLE_ERROR); $x= null; +echo "Calling...\n"; try { $x->method(); } catch (BadMethodCallException $e) { @@ -21,5 +23,7 @@ try { echo "Alive\n"; ?> --EXPECTF-- +Calling... +Raising... Caught expected Call to a member function method() on a non-object! Alive diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 4af4f984c3..01b497774e 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -2469,12 +2469,16 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); FREE_OP2(); FREE_OP1_IF_VAR(); - CHECK_EXCEPTION(); - /* Skip over arguments until fcall opcode, return NULL */ + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } + + /* No exception raised: Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -2487,6 +2491,12 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, TMP|VAR|UNUSED|CV, CONST|TMP|VAR|CV) EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index e745dd0850..e1f60d38e8 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -9312,12 +9312,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -9330,6 +9333,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CONST_HANDLER(ZEND_OPCO EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -10201,12 +10210,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_dtor(free_op2.var); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -10219,6 +10231,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_TMP_HANDLER(ZEND_OPCODE EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -11091,12 +11109,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_ptr_dtor_nogc(&free_op2.var); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -11109,6 +11130,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_VAR_HANDLER(ZEND_OPCODE EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -12561,12 +12588,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -12579,6 +12609,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMP_CV_HANDLER(ZEND_OPCODE_ EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -15823,12 +15859,16 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_ptr_dtor_nogc(&free_op1.var); - CHECK_EXCEPTION(); + + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -15841,6 +15881,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CONST_HANDLER(ZEND_OPCO EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -18193,12 +18239,16 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_dtor(free_op2.var); zval_ptr_dtor_nogc(&free_op1.var); - CHECK_EXCEPTION(); + + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -18211,6 +18261,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_TMP_HANDLER(ZEND_OPCODE EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -20524,12 +20580,16 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_ptr_dtor_nogc(&free_op2.var); zval_ptr_dtor_nogc(&free_op1.var); - CHECK_EXCEPTION(); + + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -20542,6 +20602,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_VAR_HANDLER(ZEND_OPCODE EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -24005,12 +24071,16 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_ptr_dtor_nogc(&free_op1.var); - CHECK_EXCEPTION(); + + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -24023,6 +24093,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_ EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -25671,12 +25747,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -25689,6 +25768,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CONST_HANDLER(ZEND_O EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -27103,12 +27188,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_dtor(free_op2.var); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -27121,6 +27209,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_TMP_HANDLER(ZEND_OPC EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -28441,12 +28535,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_ptr_dtor_nogc(&free_op2.var); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -28459,6 +28556,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_VAR_HANDLER(ZEND_OPC EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -30207,12 +30310,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -30225,6 +30331,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_CV_HANDLER(ZEND_OPCO EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -33470,12 +33582,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -33488,6 +33603,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST_HANDLER(ZEND_OPCOD EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -35606,12 +35727,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_dtor(free_op2.var); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -35624,6 +35748,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMP_HANDLER(ZEND_OPCODE_ EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -37797,12 +37927,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); zval_ptr_dtor_nogc(&free_op2.var); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -37815,6 +37948,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_VAR_HANDLER(ZEND_OPCODE_ EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } @@ -40989,12 +41128,15 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H zend_error(E_RECOVERABLE_ERROR, "Call to a member function %s() on a non-object", function_name_strval); - CHECK_EXCEPTION(); + if (EG(exception) != NULL) { + HANDLE_EXCEPTION(); + } /* Skip over arguments until fcall opcode, return NULL */ do { ZEND_VM_INC_OPCODE(); opline++; + if (opline->opcode == ZEND_INIT_METHOD_CALL || opline->opcode == ZEND_INIT_FCALL_BY_NAME) { nested++; } else if (opline->opcode == ZEND_DO_FCALL_BY_NAME) { @@ -41007,6 +41149,12 @@ static int ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HANDLER(ZEND_OPCODE_H EX_T(opline->result.var).var.fcall_returned_reference = 0; EX_T(opline->result.var).var.ptr_ptr = &EX_T(opline->result.var).var.ptr; } + + if ((opline + 1)->opcode == ZEND_EXT_FCALL_END) { + ZEND_VM_INC_OPCODE(); + } + + CHECK_EXCEPTION(); ZEND_VM_NEXT_OPCODE(); } |