summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBob Weinand <bobwei9@hotmail.com>2016-10-18 14:13:20 +0200
committerBob Weinand <bobwei9@hotmail.com>2016-10-18 14:14:24 +0200
commit8b177f6a2a2782107461d7153385857872e2f4b9 (patch)
tree4bce69528a6b68e42ae43702b2d3d48152073405
parent7bd4e7208e26e3e441717c0f33a154a385764d06 (diff)
downloadphp-git-8b177f6a2a2782107461d7153385857872e2f4b9.tar.gz
Fixed bug #73338 (Exception thrown from error handler may crash)
-rw-r--r--NEWS2
-rw-r--r--Zend/tests/bug73338.phpt18
-rw-r--r--Zend/zend_vm_def.h70
-rw-r--r--Zend/zend_vm_execute.h286
4 files changed, 271 insertions, 105 deletions
diff --git a/NEWS b/NEWS
index be20d3ba96..4be67717ff 100644
--- a/NEWS
+++ b/NEWS
@@ -12,6 +12,8 @@ PHP NEWS
. Fixed bug #73215 (uniqid() should use better random source). (Yasuo)
. Fixed bug #73337 (try/catch not working with two exceptions inside a same
operation). (Dmitry)
+ . Fixed bug #73338 (Exception thrown from error handler causes valgrind
+ warnings (and crashes)). (Bob, Dmitry)
- GD:
. Fixed bug #73213 (Integer overflow in imageline() with antialiasing). (cmb)
diff --git a/Zend/tests/bug73338.phpt b/Zend/tests/bug73338.phpt
new file mode 100644
index 0000000000..df4c3b66e4
--- /dev/null
+++ b/Zend/tests/bug73338.phpt
@@ -0,0 +1,18 @@
+--TEST--
+Bug #73338: Ensure exceptions in function init opcodes are cleaned properly
+--FILE--
+<?php
+
+try { call_user_func(new class { function __destruct () { throw new Error; } }); } catch (Error $e) {}
+
+set_error_handler(function() { throw new Error; });
+
+try { var_dump(new stdClass, call_user_func("fail")); } catch (Error $e) {}
+
+try { (function() { call_user_func("fail"); })(); } catch (Error $e) {}
+
+try { [new class { static function foo() {} function __destruct () { throw new Error; } }, "foo"](); } catch (Error $e) {}
+
+?>
+--EXPECTF--
+Warning: call_user_func() expects parameter 1 to be a valid callback, no array or string given in %s on line %d
diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h
index dcd460ad5d..6693ef316f 100644
--- a/Zend/zend_vm_def.h
+++ b/Zend/zend_vm_def.h
@@ -3012,15 +3012,19 @@ ZEND_VM_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|CV, CONST|TMPVAR
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ FREE_OP2();
+ FREE_OP1();
+
+ if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- FREE_OP2();
- FREE_OP1();
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSED|CV)
@@ -3161,7 +3165,7 @@ ZEND_VM_HANDLER(113, ZEND_INIT_STATIC_METHOD_CALL, CONST|VAR, CONST|TMPVAR|UNUSE
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(59, ZEND_INIT_FCALL_BY_NAME, ANY, CONST)
@@ -3283,7 +3287,6 @@ ZEND_VM_C_LABEL(try_function_name):
called_scope = NULL;
object = NULL;
}
- FREE_OP2();
} else if (OP2_TYPE != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
@@ -3297,7 +3300,6 @@ ZEND_VM_C_LABEL(try_function_name):
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
- FREE_OP2();
} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
zval *obj;
@@ -3381,7 +3383,6 @@ ZEND_VM_C_LABEL(try_function_name):
GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- FREE_OP2();
} else if ((OP2_TYPE & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
function_name = Z_REFVAL_P(function_name);
ZEND_VM_C_GOTO(try_function_name);
@@ -3396,6 +3397,18 @@ ZEND_VM_C_LABEL(try_function_name):
FREE_OP2();
HANDLE_EXCEPTION();
}
+
+ FREE_OP2();
+ if ((OP2_TYPE & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
+ }
+ if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+ zend_string_release(fbc->common.function_name);
+ zend_free_trampoline(fbc);
+ }
+ HANDLE_EXCEPTION();
+ }
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, object);
call->prev_execute_data = EX(call);
@@ -3421,6 +3434,19 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
function_name = GET_OP2_ZVAL_PTR(BP_VAR_R);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
+ called_scope = fcc.called_scope;
+ object = fcc.object;
+ if (error) {
+ efree(error);
+ /* This is the only soft error is_callable() can generate */
+ zend_error(E_DEPRECATED,
+ "Non-static method %s::%s() should not be called statically",
+ ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ FREE_OP2();
+ HANDLE_EXCEPTION();
+ }
+ }
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
if (OP2_TYPE & (IS_VAR|IS_CV)) {
@@ -3430,25 +3456,28 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
}
- called_scope = fcc.called_scope;
- object = fcc.object;
if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
- if (error) {
- efree(error);
- /* This is the only soft error is_callable() can generate */
- zend_error(E_DEPRECATED,
- "Non-static method %s::%s() should not be called statically",
- ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+
+ FREE_OP2();
+ if ((OP2_TYPE & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_CLOSURE) {
+ zend_object_release((zend_object*)func->common.prototype);
+ }
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
}
+ HANDLE_EXCEPTION();
}
} else {
zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error);
efree(error);
+ FREE_OP2();
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
func = (zend_function*)&zend_pass_function;
called_scope = NULL;
object = NULL;
@@ -3459,8 +3488,7 @@ ZEND_VM_HANDLER(118, ZEND_INIT_USER_CALL, CONST, CONST|TMPVAR|CV)
call->prev_execute_data = EX(call);
EX(call) = call;
- FREE_OP2();
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
ZEND_VM_HANDLER(69, ZEND_INIT_NS_FCALL_BY_NAME, ANY, CONST)
@@ -4946,7 +4974,7 @@ ZEND_VM_HANDLER(68, ZEND_NEW, CONST|VAR, ANY)
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
}
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
}
diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h
index 4bc72bd24f..2c90e0073e 100644
--- a/Zend/zend_vm_execute.h
+++ b/Zend/zend_vm_execute.h
@@ -1995,7 +1995,6 @@ try_function_name:
called_scope = NULL;
object = NULL;
}
-
} else if (IS_CONST != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
@@ -2009,7 +2008,6 @@ try_function_name:
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
-
} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
zval *obj;
@@ -2093,7 +2091,6 @@ try_function_name:
GC_REFCOUNT(object)++; /* For $this pointer */
}
}
-
} else if ((IS_CONST & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
function_name = Z_REFVAL_P(function_name);
goto try_function_name;
@@ -2108,6 +2105,17 @@ try_function_name:
HANDLE_EXCEPTION();
}
+
+ if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
+ }
+ if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+ zend_string_release(fbc->common.function_name);
+ zend_free_trampoline(fbc);
+ }
+ HANDLE_EXCEPTION();
+ }
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, object);
call->prev_execute_data = EX(call);
@@ -2418,7 +2426,6 @@ try_function_name:
called_scope = NULL;
object = NULL;
}
-
} else if (IS_CV != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
@@ -2432,7 +2439,6 @@ try_function_name:
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
-
} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
zval *obj;
@@ -2516,7 +2522,6 @@ try_function_name:
GC_REFCOUNT(object)++; /* For $this pointer */
}
}
-
} else if ((IS_CV & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
function_name = Z_REFVAL_P(function_name);
goto try_function_name;
@@ -2531,6 +2536,17 @@ try_function_name:
HANDLE_EXCEPTION();
}
+
+ if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
+ }
+ if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+ zend_string_release(fbc->common.function_name);
+ zend_free_trampoline(fbc);
+ }
+ HANDLE_EXCEPTION();
+ }
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, object);
call->prev_execute_data = EX(call);
@@ -2674,7 +2690,6 @@ try_function_name:
called_scope = NULL;
object = NULL;
}
- zval_ptr_dtor_nogc(free_op2);
} else if ((IS_TMP_VAR|IS_VAR) != IS_CONST &&
EXPECTED(Z_TYPE_P(function_name) == IS_OBJECT) &&
Z_OBJ_HANDLER_P(function_name, get_closure) &&
@@ -2688,7 +2703,6 @@ try_function_name:
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
- zval_ptr_dtor_nogc(free_op2);
} else if (EXPECTED(Z_TYPE_P(function_name) == IS_ARRAY) &&
zend_hash_num_elements(Z_ARRVAL_P(function_name)) == 2) {
zval *obj;
@@ -2772,7 +2786,6 @@ try_function_name:
GC_REFCOUNT(object)++; /* For $this pointer */
}
}
- zval_ptr_dtor_nogc(free_op2);
} else if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) && Z_TYPE_P(function_name) == IS_REFERENCE) {
function_name = Z_REFVAL_P(function_name);
goto try_function_name;
@@ -2787,6 +2800,18 @@ try_function_name:
zval_ptr_dtor_nogc(free_op2);
HANDLE_EXCEPTION();
}
+
+ zval_ptr_dtor_nogc(free_op2);
+ if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
+ }
+ if (fbc->common.fn_flags & ZEND_ACC_CALL_VIA_TRAMPOLINE) {
+ zend_string_release(fbc->common.function_name);
+ zend_free_trampoline(fbc);
+ }
+ HANDLE_EXCEPTION();
+ }
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, object);
call->prev_execute_data = EX(call);
@@ -3367,7 +3392,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_CONST_HANDLER(ZEND_OP
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
}
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
}
@@ -5594,13 +5619,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CO
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+
+ if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -5741,7 +5770,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -5761,6 +5790,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
function_name = EX_CONSTANT(opline->op2);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
+ called_scope = fcc.called_scope;
+ object = fcc.object;
+ if (error) {
+ efree(error);
+ /* This is the only soft error is_callable() can generate */
+ zend_error(E_DEPRECATED,
+ "Non-static method %s::%s() should not be called statically",
+ ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
+ }
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
if (IS_CONST & (IS_VAR|IS_CV)) {
@@ -5770,25 +5812,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
}
- called_scope = fcc.called_scope;
- object = fcc.object;
if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
- if (error) {
- efree(error);
- /* This is the only soft error is_callable() can generate */
- zend_error(E_DEPRECATED,
- "Non-static method %s::%s() should not be called statically",
- ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+
+ if ((IS_CONST & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_CLOSURE) {
+ zend_object_release((zend_object*)func->common.prototype);
}
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
+ }
+ HANDLE_EXCEPTION();
}
} else {
zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error);
efree(error);
+
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
func = (zend_function*)&zend_pass_function;
called_scope = NULL;
object = NULL;
@@ -5799,7 +5843,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CONS
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -7740,7 +7784,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_CONST_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9346,13 +9390,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_CV
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+
+ if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9493,7 +9541,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -9513,6 +9561,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
function_name = _get_zval_ptr_cv_BP_VAR_R(execute_data, opline->op2.var);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
+ called_scope = fcc.called_scope;
+ object = fcc.object;
+ if (error) {
+ efree(error);
+ /* This is the only soft error is_callable() can generate */
+ zend_error(E_DEPRECATED,
+ "Non-static method %s::%s() should not be called statically",
+ ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
+ if (UNEXPECTED(EG(exception) != NULL)) {
+
+ HANDLE_EXCEPTION();
+ }
+ }
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
if (IS_CV & (IS_VAR|IS_CV)) {
@@ -9522,25 +9583,27 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
}
- called_scope = fcc.called_scope;
- object = fcc.object;
if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
- if (error) {
- efree(error);
- /* This is the only soft error is_callable() can generate */
- zend_error(E_DEPRECATED,
- "Non-static method %s::%s() should not be called statically",
- ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+
+ if ((IS_CV & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_CLOSURE) {
+ zend_object_release((zend_object*)func->common.prototype);
+ }
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
}
+ HANDLE_EXCEPTION();
}
} else {
zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error);
efree(error);
+
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
func = (zend_function*)&zend_pass_function;
called_scope = NULL;
object = NULL;
@@ -9551,7 +9614,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_CV_H
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CATCH_SPEC_CONST_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11176,14 +11239,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CONST_TM
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ zval_ptr_dtor_nogc(free_op2);
+
+ if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op2);
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11324,7 +11391,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_C
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -11344,6 +11411,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
function_name = _get_zval_ptr_var(opline->op2.var, execute_data, &free_op2);
if (zend_is_callable_ex(function_name, NULL, 0, NULL, &fcc, &error)) {
func = fcc.function_handler;
+ called_scope = fcc.called_scope;
+ object = fcc.object;
+ if (error) {
+ efree(error);
+ /* This is the only soft error is_callable() can generate */
+ zend_error(E_DEPRECATED,
+ "Non-static method %s::%s() should not be called statically",
+ ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
+ if (UNEXPECTED(EG(exception) != NULL)) {
+ zval_ptr_dtor_nogc(free_op2);
+ HANDLE_EXCEPTION();
+ }
+ }
if (func->common.fn_flags & ZEND_ACC_CLOSURE) {
/* Delay closure destruction until its invocation */
if ((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_CV)) {
@@ -11353,25 +11433,28 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
GC_REFCOUNT((zend_object*)func->common.prototype)++;
call_info |= ZEND_CALL_CLOSURE;
}
- called_scope = fcc.called_scope;
- object = fcc.object;
if (object) {
call_info |= ZEND_CALL_RELEASE_THIS;
GC_REFCOUNT(object)++; /* For $this pointer */
}
- if (error) {
- efree(error);
- /* This is the only soft error is_callable() can generate */
- zend_error(E_DEPRECATED,
- "Non-static method %s::%s() should not be called statically",
- ZSTR_VAL(func->common.scope->name), ZSTR_VAL(func->common.function_name));
- if (UNEXPECTED(EG(exception) != NULL)) {
- HANDLE_EXCEPTION();
+
+ zval_ptr_dtor_nogc(free_op2);
+ if (((IS_TMP_VAR|IS_VAR) & (IS_TMP_VAR|IS_VAR)) && UNEXPECTED(EG(exception))) {
+ if (call_info & ZEND_CALL_CLOSURE) {
+ zend_object_release((zend_object*)func->common.prototype);
}
+ if (call_info & ZEND_CALL_RELEASE_THIS) {
+ zend_object_release(object);
+ }
+ HANDLE_EXCEPTION();
}
} else {
zend_internal_type_error(EX_USES_STRICT_TYPES(), "%s() expects parameter 1 to be a valid callback, %s", Z_STRVAL_P(EX_CONSTANT(opline->op1)), error);
efree(error);
+ zval_ptr_dtor_nogc(free_op2);
+ if (UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
func = (zend_function*)&zend_pass_function;
called_scope = NULL;
object = NULL;
@@ -11382,8 +11465,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_USER_CALL_SPEC_CONST_TMPV
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op2);
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CONST_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -15482,7 +15564,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_NEW_SPEC_VAR_HANDLER(ZEND_OPCO
ZVAL_COPY(EX_VAR(opline->result.var), &object_zval);
}
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
}
@@ -17726,7 +17808,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_VAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -19365,7 +19447,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_VERIFY_RETURN_TYPE_SPEC_VAR_UNUSED_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -21010,7 +21092,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -22602,7 +22684,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_STATIC_METHOD_CALL_SPEC_V
call->prev_execute_data = EX(call);
EX(call) = call;
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_ADD_ARRAY_ELEMENT_SPEC_VAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -23985,13 +24067,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+
+ if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_FETCH_CONSTANT_SPEC_UNUSED_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -26412,13 +26498,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+
+ if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -27916,14 +28006,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ zval_ptr_dtor_nogc(free_op2);
+
+ if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op2);
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_ARRAY_SPEC_UNUSED_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -32200,13 +32294,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CONST
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+
+ if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -37304,13 +37402,17 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+
+ if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -39899,14 +40001,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ zval_ptr_dtor_nogc(free_op2);
+
+ if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op2);
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_CV_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -42141,14 +42247,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ zval_ptr_dtor_nogc(free_op1);
+
+ if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op1);
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CONST_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -44289,14 +44399,18 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ zval_ptr_dtor_nogc(free_op1);
+
+ if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op1);
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS)
@@ -45435,15 +45549,19 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
GC_REFCOUNT(obj)++; /* For $this pointer */
}
+ zval_ptr_dtor_nogc(free_op2);
+ zval_ptr_dtor_nogc(free_op1);
+
+ if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && UNEXPECTED(EG(exception))) {
+ HANDLE_EXCEPTION();
+ }
+
call = zend_vm_stack_push_call_frame(call_info,
fbc, opline->extended_value, called_scope, obj);
call->prev_execute_data = EX(call);
EX(call) = call;
- zval_ptr_dtor_nogc(free_op2);
- zval_ptr_dtor_nogc(free_op1);
-
- ZEND_VM_NEXT_OPCODE_CHECK_EXCEPTION();
+ ZEND_VM_NEXT_OPCODE();
}
static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_CASE_SPEC_TMPVAR_TMPVAR_HANDLER(ZEND_OPCODE_HANDLER_ARGS)