Commit 5d2456f9740 for php.net
commit 5d2456f97403934ccd2aa1fa44a4a4bcc9a55530
Author: David Carlier <devnexen@gmail.com>
Date: Mon Jan 5 19:04:42 2026 +0000
Fix GH-20840: crash on nested object with var_dump().
mitigate it with stack check limit.
close GH-20843
diff --git a/NEWS b/NEWS
index fc4f5d3d297..cc216648152 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,8 @@ PHP NEWS
- Standard:
. Fixed bug #74357 (lchown fails to change ownership of symlink with ZTS)
(Jakub Zelenka)
+ . Fixed bug GH-20843 (var_dump() crash with nested objects)
+ (David Carlier)
15 Jan 2026, PHP 8.4.17
diff --git a/ext/standard/tests/general_functions/gh20840.phpt b/ext/standard/tests/general_functions/gh20840.phpt
new file mode 100644
index 00000000000..839b4728be1
--- /dev/null
+++ b/ext/standard/tests/general_functions/gh20840.phpt
@@ -0,0 +1,38 @@
+--TEST--
+GH-20840 (var_dump() crash with nested objects)
+--CREDITS--
+bendrissou
+--SKIPIF--
+<?php
+if (ini_get('zend.max_allowed_stack_size') === false) {
+ die('skip No stack limit support');
+}
+if (getenv('SKIP_ASAN')) {
+ die('skip ASAN needs different stack limit setting due to more stack space usage');
+}
+?>
+--INI--
+zend.max_allowed_stack_size=512K
+--FILE--
+<?php
+class Node {
+ public $next;
+}
+
+$firstNode = new Node();
+$node = $firstNode;
+
+for ($i = 0; $i < 50000; $i++) {
+ $newNode = new Node();
+ $node->next = $newNode;
+ $node = $newNode;
+}
+
+var_dump($firstNode);
+
+while ($next = $firstNode->next) {
+ $firstNode->next = $next->next;
+}
+?>
+--EXPECTREGEX--
+^object\(Node\)#\d+ \(\d+\).*(nesting level too deep|["\s}]*)$
diff --git a/ext/standard/var.c b/ext/standard/var.c
index df262eb520c..acb605d2eab 100644
--- a/ext/standard/var.c
+++ b/ext/standard/var.c
@@ -56,6 +56,12 @@ static void php_object_property_dump(zend_property_info *prop_info, zval *zv, ze
{
const char *prop_name, *class_name;
+#ifdef ZEND_CHECK_STACK_LIMIT
+ if (UNEXPECTED(zend_call_stack_overflowed(EG(stack_limit)))) {
+ php_printf("%*cnesting level too deep", level + 1, ' ');
+ return;
+ }
+#endif
if (key == NULL) { /* numeric key */
php_printf("%*c[" ZEND_LONG_FMT "]=>\n", level + 1, ' ', index);
} else { /* string key */