Skip to content

Commit fb8993c

Browse files
committed
Make Exception::$trace typed array property
1 parent 01e86d6 commit fb8993c

File tree

4 files changed

+26
-38
lines changed

4 files changed

+26
-38
lines changed

Zend/zend_API.c

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3586,20 +3586,14 @@ ZEND_API int zend_declare_typed_property(zend_class_entry *ce, zend_string *name
35863586
Z_PROP_FLAG_P(property_default_ptr) = Z_ISUNDEF_P(property) ? IS_PROP_UNINIT : 0;
35873587
}
35883588
if (ce->type & ZEND_INTERNAL_CLASS) {
3589-
switch(Z_TYPE_P(property)) {
3590-
case IS_ARRAY:
3591-
case IS_OBJECT:
3592-
case IS_RESOURCE:
3593-
zend_error_noreturn(E_CORE_ERROR, "Internal zval's can't be arrays, objects or resources");
3594-
break;
3595-
default:
3596-
break;
3597-
}
3598-
35993589
/* Must be interned to avoid ZTS data races */
36003590
if (is_persistent_class(ce)) {
36013591
name = zend_new_interned_string(zend_string_copy(name));
36023592
}
3593+
3594+
if (Z_REFCOUNTED_P(property)) {
3595+
zend_error_noreturn(E_CORE_ERROR, "Internal zvals cannot be refcounted");
3596+
}
36033597
}
36043598

36053599
if (access_type & ZEND_ACC_PUBLIC) {

Zend/zend_exceptions.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -606,10 +606,12 @@ ZEND_METHOD(Exception, getTraceAsString)
606606
base_ce = i_get_exception_base(object);
607607

608608
trace = zend_read_property_ex(base_ce, object, ZSTR_KNOWN(ZEND_STR_TRACE), 1, &rv);
609-
if (Z_TYPE_P(trace) != IS_ARRAY) {
610-
zend_type_error("Trace is not an array");
611-
return;
609+
if (EG(exception)) {
610+
RETURN_THROWS();
612611
}
612+
613+
/* Type should be guaranteed by property type. */
614+
ZEND_ASSERT(Z_TYPE_P(trace) == IS_ARRAY);
613615
ZEND_HASH_FOREACH_NUM_KEY_VAL(Z_ARRVAL_P(trace), index, frame) {
614616
if (Z_TYPE_P(frame) != IS_ARRAY) {
615617
zend_error(E_WARNING, "Expected array for frame " ZEND_ULONG_FMT, index);
@@ -736,12 +738,19 @@ ZEND_METHOD(Exception, __toString)
736738

737739
static void declare_exception_properties(zend_class_entry *ce)
738740
{
741+
zval val;
742+
739743
zend_declare_property_string(ce, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED);
740744
zend_declare_property_string(ce, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE);
741745
zend_declare_property_long(ce, "code", sizeof("code")-1, 0, ZEND_ACC_PROTECTED);
742746
zend_declare_property_null(ce, "file", sizeof("file")-1, ZEND_ACC_PROTECTED);
743747
zend_declare_property_null(ce, "line", sizeof("line")-1, ZEND_ACC_PROTECTED);
744-
zend_declare_property_null(ce, "trace", sizeof("trace")-1, ZEND_ACC_PRIVATE);
748+
749+
ZVAL_EMPTY_ARRAY(&val);
750+
zend_declare_typed_property(
751+
ce, ZSTR_KNOWN(ZEND_STR_TRACE), &val, ZEND_ACC_PRIVATE, NULL,
752+
(zend_type) ZEND_TYPE_INIT_MASK(MAY_BE_ARRAY));
753+
745754
zend_declare_property_null(ce, "previous", sizeof("previous")-1, ZEND_ACC_PRIVATE);
746755
}
747756

ext/standard/tests/serialize/bug69152.phpt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ $x->test();
99

1010
?>
1111
--EXPECTF--
12-
Fatal error: Uncaught TypeError: Trace is not an array in %s:%d
13-
%a
12+
Fatal error: Uncaught TypeError: Cannot assign string to property Exception::$trace of type array in %s:%d
13+
Stack trace:
14+
#0 %s(%d): unserialize('O:9:"exception"...')
15+
#1 {main}
1416
thrown in %s on line %d

ext/standard/tests/serialize/bug70963.phpt

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,8 @@ var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".
66
var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".'trace";s:4:"test";}i:1;r:3;}'));
77
?>
88
--EXPECTF--
9-
array(2) {
10-
[0]=>
11-
object(Exception)#%d (6) {
12-
["message":protected]=>
13-
string(0) ""
14-
["string":"Exception":private]=>
15-
string(0) ""
16-
["code":protected]=>
17-
int(0)
18-
["file":protected]=>
19-
string(%d) "%s"
20-
["line":protected]=>
21-
int(2)
22-
["previous":"Exception":private]=>
23-
NULL
24-
}
25-
[1]=>
26-
string(4) "test"
27-
}
28-
29-
Notice: unserialize(): Error at offset %d of %d bytes in %sbug70963.php on line 3
30-
bool(false)
9+
Fatal error: Uncaught TypeError: Cannot assign string to property Exception::$trace of type array in %s:%d
10+
Stack trace:
11+
#0 %s(%d): unserialize('a:2:{i:0;O:9:"e...')
12+
#1 {main}
13+
thrown in %s on line %d

0 commit comments

Comments
 (0)