Skip to content

Commit 5014aaa

Browse files
committed
Fix GH-20840: crash on nested object with var_dump().
mitigate it with stack check limit. close GH-20843
1 parent 1c9f117 commit 5014aaa

File tree

2 files changed

+45
-1
lines changed

2 files changed

+45
-1
lines changed
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
--TEST--
2+
GH-20840 (var_dump() crash with nested objects)
3+
--CREDITS--
4+
bendrissou
5+
--SKIPIF--
6+
<?php
7+
if (ini_get('zend.max_allowed_stack_size') === false) {
8+
die('skip No stack limit support');
9+
}
10+
if (getenv('SKIP_ASAN')) {
11+
die('skip ASAN needs different stack limit setting due to more stack space usage');
12+
}
13+
?>
14+
--INI--
15+
zend.max_allowed_stack_size=512K
16+
--FILE--
17+
<?php
18+
class Node {
19+
public $next;
20+
}
21+
22+
$firstNode = new Node();
23+
$node = $firstNode;
24+
25+
for ($i = 0; $i < 50000; $i++) {
26+
$newNode = new Node();
27+
$node->next = $newNode;
28+
$node = $newNode;
29+
}
30+
31+
var_dump($firstNode);
32+
33+
while ($next = $firstNode->next) {
34+
$firstNode->next = $next->next;
35+
}
36+
?>
37+
--EXPECTREGEX--
38+
^object\(Node\)#\d+ \(\d+\).*(nesting level too deep|["\s}]*)$

ext/standard/var.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ static void php_object_property_dump(zend_property_info *prop_info, zval *zv, ze
5656
{
5757
const char *prop_name, *class_name;
5858

59+
#ifdef ZEND_CHECK_STACK_LIMIT
60+
if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
61+
php_printf("%*cnesting level too deep", level + 1, ' ');
62+
return;
63+
}
64+
#endif
5965
if (key == NULL) { /* numeric key */
6066
php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index);
6167
} else { /* string key */
@@ -80,7 +86,7 @@ static void php_object_property_dump(zend_property_info *prop_info, zval *zv, ze
8086
ZEND_ASSERT(ZEND_TYPE_IS_SET(prop_info->type));
8187
zend_string *type_str = zend_type_to_string(prop_info->type);
8288
php_printf("%*cuninitialized(%s)\n",
83-
level + 1, ' ', ZSTR_VAL(type_str));
89+
level + 1, ' ', ZSTR_VAL(type_str));
8490
zend_string_release(type_str);
8591
} else {
8692
php_var_dump(zv, level + 2);

0 commit comments

Comments
 (0)