mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Fix GH-16574: Incorrect error "undefined method" messages
The `get_method` object handler may change the object pointer. SPL does this in its iterator implementations. This causes the error message to change to another class which is confusing to the user. JIT handles this correctly. This patch aligns behaviour with JIT. Closes GH-16576.
This commit is contained in:
parent
9ee204f2e3
commit
e9283c0819
4 changed files with 32 additions and 13 deletions
4
NEWS
4
NEWS
|
@ -2,6 +2,10 @@ PHP NEWS
|
|||
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||
?? ??? ????, PHP 8.4.0RC4
|
||||
|
||||
- Core:
|
||||
. Fixed bug GH-16574 (Incorrect error "undefined method" messages).
|
||||
(nielsdos)
|
||||
|
||||
- GD:
|
||||
. Fixed bug GH-16559 (UBSan abort in ext/gd/libgd/gd_interpolation.c:1007).
|
||||
(nielsdos)
|
||||
|
|
|
@ -3625,7 +3625,7 @@ ZEND_VM_HOT_OBJ_HANDLER(112, ZEND_INIT_METHOD_CALL, CONST|TMPVAR|UNUSED|THIS|CV,
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((OP2_TYPE == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
FREE_OP2();
|
||||
if ((OP1_TYPE & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
|
24
Zend/zend_vm_execute.h
generated
24
Zend/zend_vm_execute.h
generated
|
@ -7209,7 +7209,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -9773,7 +9773,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
|
||||
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -12255,7 +12255,7 @@ static ZEND_VM_COLD ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if ((IS_CONST & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -16648,7 +16648,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -18141,7 +18141,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_T
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
|
||||
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -19548,7 +19548,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_TMPVAR_C
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if (((IS_TMP_VAR|IS_VAR) & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -34934,7 +34934,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -37103,7 +37103,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_T
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
|
||||
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -39748,7 +39748,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_UNUSED_C
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if ((IS_UNUSED & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -44864,7 +44864,7 @@ static ZEND_VM_HOT ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_S
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CONST == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -48758,7 +48758,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_TMPVA
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), (((IS_TMP_VAR|IS_VAR) == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
zval_ptr_dtor_nogc(EX_VAR(opline->op2.var));
|
||||
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
@ -54353,7 +54353,7 @@ static ZEND_OPCODE_HANDLER_RET ZEND_FASTCALL ZEND_INIT_METHOD_CALL_SPEC_CV_CV_HA
|
|||
fbc = obj->handlers->get_method(&obj, Z_STR_P(function_name), ((IS_CV == IS_CONST) ? (RT_CONSTANT(opline, opline->op2) + 1) : NULL));
|
||||
if (UNEXPECTED(fbc == NULL)) {
|
||||
if (EXPECTED(!EG(exception))) {
|
||||
zend_undefined_method(obj->ce, Z_STR_P(function_name));
|
||||
zend_undefined_method(orig_obj->ce, Z_STR_P(function_name));
|
||||
}
|
||||
|
||||
if ((IS_CV & (IS_VAR|IS_TMP_VAR)) && GC_DELREF(orig_obj) == 0) {
|
||||
|
|
15
ext/spl/tests/gh16574.phpt
Normal file
15
ext/spl/tests/gh16574.phpt
Normal file
|
@ -0,0 +1,15 @@
|
|||
--TEST--
|
||||
GH-16574 (Incorrect error "undefined method" messages)
|
||||
--CREDITS--
|
||||
YuanchengJiang
|
||||
--FILE--
|
||||
<?php
|
||||
$i = new ArrayIterator([1,1,1,1,1]);
|
||||
$i = new CachingIterator($i, CachingIterator::FULL_CACHE);
|
||||
$i->doesnotexist("x");
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught Error: Call to undefined method CachingIterator::doesnotexist() in %s:%d
|
||||
Stack trace:
|
||||
#0 {main}
|
||||
thrown in %s on line %d
|
Loading…
Add table
Add a link
Reference in a new issue