mirror of
https://github.com/php/php-src.git
synced 2024-11-23 18:04:36 +08:00
Make Exception::$trace typed array property
This is a private property, so we are allowed to add a type. The new declaration of the property is: private array $trace = []; This ensures that Exception::getTrace() does indeed return an array. Userland code that was modifying the property through refleciton may have to be adjusted to assign an array (instead of null, for example). Closes GH-5636.
This commit is contained in:
parent
c16dbed0c4
commit
aaae77f7f1
@ -3586,20 +3586,14 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name
|
||||
Z_PROP_FLAG_P(property_default_ptr) = Z_ISUNDEF_P(property) ? IS_PROP_UNINIT : 0;
|
||||
}
|
||||
if (ce->type & ZEND_INTERNAL_CLASS) {
|
||||
switch(Z_TYPE_P(property)) {
|
||||
case IS_ARRAY:
|
||||
case IS_OBJECT:
|
||||
case IS_RESOURCE:
|
||||
zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Must be interned to avoid ZTS data races */
|
||||
if (is_persistent_class(ce)) {
|
||||
name = zend_new_interned_string(zend_string_copy(name));
|
||||
}
|
||||
|
||||
if (Z_REFCOUNTED_P(property)) {
|
||||
zend_error_noreturn(E_CORE_ERROR, "Internal zvals cannot be refcounted");
|
||||
}
|
||||
}
|
||||
|
||||
if (access_type & ZEND_ACC_PUBLIC) {
|
||||
|
@ -606,10 +606,12 @@ ZEND_METHOD(Exception, getTraceAsString)
|
||||
base_ce = i_get_exception_base(object);
|
||||
|
||||
trace = zend_read_property_ex(base_ce, object, ZSTR_KNOWN(ZEND_STR_TRACE), 1, &rv);
|
||||
if (Z_TYPE_P(trace) != IS_ARRAY) {
|
||||
zend_type_error("Trace is not an array");
|
||||
return;
|
||||
if (EG(exception)) {
|
||||
RETURN_THROWS();
|
||||
}
|
||||
|
||||
/* Type should be guaranteed by property type. */
|
||||
ZEND_ASSERT(Z_TYPE_P(trace) == IS_ARRAY);
|
||||
ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(trace), index, frame) {
|
||||
if (Z_TYPE_P(frame) != IS_ARRAY) {
|
||||
zend_error(E_WARNING, "Expected array for frame " ZEND_ULONG_FMT, index);
|
||||
@ -736,12 +738,19 @@ ZEND_METHOD(Exception, __toString)
|
||||
|
||||
static void declare_exception_properties(zend_class_entry *ce)
|
||||
{
|
||||
zval val;
|
||||
|
||||
zend_declare_property_string(ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
|
||||
zend_declare_property_string(ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
|
||||
zend_declare_property_long(ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
|
||||
zend_declare_property_null(ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
|
||||
zend_declare_property_null(ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
|
||||
zend_declare_property_null(ce, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE);
|
||||
|
||||
ZVAL_EMPTY_ARRAY(&val);
|
||||
zend_declare_typed_property(
|
||||
ce, ZSTR_KNOWN(ZEND_STR_TRACE), &val, ZEND_ACC_PRIVATE, NULL,
|
||||
(zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
|
||||
|
||||
zend_declare_property_null(ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,8 @@ $x->test();
|
||||
|
||||
?>
|
||||
--EXPECTF--
|
||||
Fatal error: Uncaught TypeError: Trace is not an array in %s:%d
|
||||
%a
|
||||
Fatal error: Uncaught TypeError: Cannot assign string to property Exception::$trace of type array in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): unserialize('O:9:"exception"...')
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
||||
|
@ -6,25 +6,8 @@ var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".
|
||||
var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".'trace";s:4:"test";}i:1;r:3;}'));
|
||||
?>
|
||||
--EXPECTF--
|
||||
array(2) {
|
||||
[0]=>
|
||||
object(Exception)#%d (6) {
|
||||
["message":protected]=>
|
||||
string(0) ""
|
||||
["string":"Exception":private]=>
|
||||
string(0) ""
|
||||
["code":protected]=>
|
||||
int(0)
|
||||
["file":protected]=>
|
||||
string(%d) "%s"
|
||||
["line":protected]=>
|
||||
int(2)
|
||||
["previous":"Exception":private]=>
|
||||
NULL
|
||||
}
|
||||
[1]=>
|
||||
string(4) "test"
|
||||
}
|
||||
|
||||
Notice: unserialize(): Error at offset %d of %d bytes in %sbug70963.php on line 3
|
||||
bool(false)
|
||||
Fatal error: Uncaught TypeError: Cannot assign string to property Exception::$trace of type array in %s:%d
|
||||
Stack trace:
|
||||
#0 %s(%d): unserialize('a:2:{i:0;O:9:"e...')
|
||||
#1 {main}
|
||||
thrown in %s on line %d
|
||||
|
@ -37,7 +37,7 @@ string(183) "Class [ <internal:Core> class stdClass ] {
|
||||
}
|
||||
|
||||
"
|
||||
string(2159) "Class [ <internal:Core> class Exception implements Throwable, Stringable ] {
|
||||
string(2166) "Class [ <internal:Core> class Exception implements Throwable, Stringable ] {
|
||||
|
||||
- Constants [0] {
|
||||
}
|
||||
@ -54,7 +54,7 @@ string(2159) "Class [ <internal:Core> class Exception implements Throwable, Stri
|
||||
Property [ protected $code = 0 ]
|
||||
Property [ protected $file = NULL ]
|
||||
Property [ protected $line = NULL ]
|
||||
Property [ private $trace = NULL ]
|
||||
Property [ private array $trace = Array ]
|
||||
Property [ private $previous = NULL ]
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user