mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Merge branch 'PHP-8.4'
* PHP-8.4: NEWS for GH-16196 NEWS for GH-16196 NEWS for GH-16196 Handle references properties of the Exception class
This commit is contained in:
commit
6c5749f34a
2 changed files with 43 additions and 3 deletions
34
Zend/tests/gh16188.phpt
Normal file
34
Zend/tests/gh16188.phpt
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
--TEST--
|
||||||
|
GH-16188 (Assertion failure in Zend/zend_exceptions.c)
|
||||||
|
--FILE--
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$re = new TypeError();
|
||||||
|
array_walk($re, function (&$item, $key) use (&$re) {
|
||||||
|
if ($key === "\x00Error\x00previous") {
|
||||||
|
$item = new Exception();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
printf("getTraceAsString:\n%s\n\n", $re->getTraceAsString());
|
||||||
|
printf("getPrevious:\n%s\n\n", get_class($re->getPrevious()));
|
||||||
|
printf("__toString:\n%s\n\n", $re);
|
||||||
|
|
||||||
|
?>
|
||||||
|
==DONE==
|
||||||
|
--EXPECTF--
|
||||||
|
getTraceAsString:
|
||||||
|
#0 {main}
|
||||||
|
|
||||||
|
getPrevious:
|
||||||
|
Exception
|
||||||
|
|
||||||
|
__toString:
|
||||||
|
Exception in %s:%d
|
||||||
|
Stack trace:%A
|
||||||
|
#%d {main}
|
||||||
|
|
||||||
|
Next TypeError in %s:%d
|
||||||
|
Stack trace:%A
|
||||||
|
#%d {main}
|
||||||
|
|
||||||
|
==DONE==
|
|
@ -116,15 +116,18 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
|
||||||
ex = &zv;
|
ex = &zv;
|
||||||
do {
|
do {
|
||||||
ancestor = zend_read_property_ex(i_get_exception_base(add_previous), add_previous, ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv);
|
ancestor = zend_read_property_ex(i_get_exception_base(add_previous), add_previous, ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv);
|
||||||
|
ZVAL_DEREF(ancestor);
|
||||||
while (Z_TYPE_P(ancestor) == IS_OBJECT) {
|
while (Z_TYPE_P(ancestor) == IS_OBJECT) {
|
||||||
if (Z_OBJ_P(ancestor) == Z_OBJ_P(ex)) {
|
if (Z_OBJ_P(ancestor) == Z_OBJ_P(ex)) {
|
||||||
OBJ_RELEASE(add_previous);
|
OBJ_RELEASE(add_previous);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ancestor = zend_read_property_ex(i_get_exception_base(Z_OBJ_P(ancestor)), Z_OBJ_P(ancestor), ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv);
|
ancestor = zend_read_property_ex(i_get_exception_base(Z_OBJ_P(ancestor)), Z_OBJ_P(ancestor), ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv);
|
||||||
|
ZVAL_DEREF(ancestor);
|
||||||
}
|
}
|
||||||
base_ce = i_get_exception_base(Z_OBJ_P(ex));
|
base_ce = i_get_exception_base(Z_OBJ_P(ex));
|
||||||
previous = zend_read_property_ex(base_ce, Z_OBJ_P(ex), ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv);
|
previous = zend_read_property_ex(base_ce, Z_OBJ_P(ex), ZSTR_KNOWN(ZEND_STR_PREVIOUS), 1, &rv);
|
||||||
|
ZVAL_DEREF(previous);
|
||||||
if (Z_TYPE_P(previous) == IS_NULL) {
|
if (Z_TYPE_P(previous) == IS_NULL) {
|
||||||
zend_update_property_ex(base_ce, Z_OBJ_P(ex), ZSTR_KNOWN(ZEND_STR_PREVIOUS), &pv);
|
zend_update_property_ex(base_ce, Z_OBJ_P(ex), ZSTR_KNOWN(ZEND_STR_PREVIOUS), &pv);
|
||||||
GC_DELREF(add_previous);
|
GC_DELREF(add_previous);
|
||||||
|
@ -626,6 +629,7 @@ ZEND_METHOD(Exception, getTraceAsString)
|
||||||
RETURN_THROWS();
|
RETURN_THROWS();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZVAL_DEREF(trace);
|
||||||
/* Type should be guaranteed by property type. */
|
/* Type should be guaranteed by property type. */
|
||||||
ZEND_ASSERT(Z_TYPE_P(trace) == IS_ARRAY);
|
ZEND_ASSERT(Z_TYPE_P(trace) == IS_ARRAY);
|
||||||
RETURN_NEW_STR(zend_trace_to_string(Z_ARRVAL_P(trace), /* include_main */ true));
|
RETURN_NEW_STR(zend_trace_to_string(Z_ARRVAL_P(trace), /* include_main */ true));
|
||||||
|
@ -639,7 +643,7 @@ ZEND_METHOD(Exception, getPrevious)
|
||||||
|
|
||||||
ZEND_PARSE_PARAMETERS_NONE();
|
ZEND_PARSE_PARAMETERS_NONE();
|
||||||
|
|
||||||
ZVAL_COPY(return_value, GET_PROPERTY_SILENT(ZEND_THIS, ZEND_STR_PREVIOUS));
|
ZVAL_COPY_DEREF(return_value, GET_PROPERTY_SILENT(ZEND_THIS, ZEND_STR_PREVIOUS));
|
||||||
} /* }}} */
|
} /* }}} */
|
||||||
|
|
||||||
/* {{{ Obtain the string representation of the Exception object */
|
/* {{{ Obtain the string representation of the Exception object */
|
||||||
|
@ -713,7 +717,8 @@ ZEND_METHOD(Exception, __toString)
|
||||||
|
|
||||||
Z_PROTECT_RECURSION_P(exception);
|
Z_PROTECT_RECURSION_P(exception);
|
||||||
exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS);
|
exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS);
|
||||||
if (exception && Z_TYPE_P(exception) == IS_OBJECT && Z_IS_RECURSIVE_P(exception)) {
|
ZVAL_DEREF(exception);
|
||||||
|
if (Z_TYPE_P(exception) == IS_OBJECT && Z_IS_RECURSIVE_P(exception)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -721,13 +726,14 @@ ZEND_METHOD(Exception, __toString)
|
||||||
|
|
||||||
exception = ZEND_THIS;
|
exception = ZEND_THIS;
|
||||||
/* Reset apply counts */
|
/* Reset apply counts */
|
||||||
while (exception && Z_TYPE_P(exception) == IS_OBJECT && (base_ce = i_get_exception_base(Z_OBJ_P(exception))) && instanceof_function(Z_OBJCE_P(exception), base_ce)) {
|
while (Z_TYPE_P(exception) == IS_OBJECT && (base_ce = i_get_exception_base(Z_OBJ_P(exception))) && instanceof_function(Z_OBJCE_P(exception), base_ce)) {
|
||||||
if (Z_IS_RECURSIVE_P(exception)) {
|
if (Z_IS_RECURSIVE_P(exception)) {
|
||||||
Z_UNPROTECT_RECURSION_P(exception);
|
Z_UNPROTECT_RECURSION_P(exception);
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS);
|
exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS);
|
||||||
|
ZVAL_DEREF(exception);
|
||||||
}
|
}
|
||||||
|
|
||||||
exception = ZEND_THIS;
|
exception = ZEND_THIS;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue