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 */