mirror of
https://github.com/php/php-src.git
synced 2025-08-15 21:48:51 +02:00
Handle references properties of the Exception class
Fixes GH-16188 Closes GH-16196
This commit is contained in:
parent
a2bdfeff4f
commit
c2115a43e3
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==
|
|
@ -115,15 +115,18 @@ void zend_exception_set_previous(zend_object *exception, zend_object *add_previo
|
|||
ex = &zv;
|
||||
do {
|
||||
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) {
|
||||
if (Z_OBJ_P(ancestor) == Z_OBJ_P(ex)) {
|
||||
OBJ_RELEASE(add_previous);
|
||||
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);
|
||||
ZVAL_DEREF(ancestor);
|
||||
}
|
||||
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);
|
||||
ZVAL_DEREF(previous);
|
||||
if (Z_TYPE_P(previous) == IS_NULL) {
|
||||
zend_update_property_ex(base_ce, Z_OBJ_P(ex), ZSTR_KNOWN(ZEND_STR_PREVIOUS), &pv);
|
||||
GC_DELREF(add_previous);
|
||||
|
@ -630,6 +633,7 @@ ZEND_METHOD(Exception, getTraceAsString)
|
|||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
ZVAL_DEREF(trace);
|
||||
/* Type should be guaranteed by property type. */
|
||||
ZEND_ASSERT(Z_TYPE_P(trace) == IS_ARRAY);
|
||||
RETURN_NEW_STR(zend_trace_to_string(Z_ARRVAL_P(trace), /* include_main */ true));
|
||||
|
@ -643,7 +647,7 @@ ZEND_METHOD(Exception, getPrevious)
|
|||
|
||||
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 */
|
||||
|
@ -723,7 +727,8 @@ ZEND_METHOD(Exception, __toString)
|
|||
|
||||
Z_PROTECT_RECURSION_P(exception);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -731,13 +736,14 @@ ZEND_METHOD(Exception, __toString)
|
|||
|
||||
exception = ZEND_THIS;
|
||||
/* 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)) {
|
||||
Z_UNPROTECT_RECURSION_P(exception);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
exception = GET_PROPERTY(exception, ZEND_STR_PREVIOUS);
|
||||
ZVAL_DEREF(exception);
|
||||
}
|
||||
|
||||
exception = ZEND_THIS;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue