Commit d9cbc3117c4 for php.net

commit d9cbc3117c4186766f67723c6ed765c80d55fa96
Author: Niels Dossche <7771979+ndossche@users.noreply.github.com>
Date:   Wed Jan 21 01:12:55 2026 +0100

    Fix hooked object properties overflow

    The computed number of properties using zend_hash_num_elements(zobj->properties)
    is incorrect when the object contains virtual properties. We don't have a
    trivial way to find the number of properties virtual properties that need to be
    added to this number, so just append with zend_hash_add_new() instead.

    Fixes GH-20479
    Closes GH-20988

diff --git a/NEWS b/NEWS
index 7d90a01f51d..9b8840c39cd 100644
--- a/NEWS
+++ b/NEWS
@@ -15,6 +15,7 @@ PHP                                                                        NEWS
   . Fix OSS-Fuzz #438780145 (Nested finally with repeated return type check may
     uaf). (ilutov)
   . Fixed bug GH-20905 (Lazy proxy bailing __clone assertion). (ilutov)
+  . Fixed bug GH-20479 (Hooked object properties overflow). (ndossche)

 - Date:
   . Update timelib to 2022.16. (Derick)
diff --git a/Zend/tests/property_hooks/gh20479.phpt b/Zend/tests/property_hooks/gh20479.phpt
new file mode 100644
index 00000000000..c53c4e4240c
--- /dev/null
+++ b/Zend/tests/property_hooks/gh20479.phpt
@@ -0,0 +1,40 @@
+--TEST--
+GH-20479: Hooked object properties overflow
+--CREDITS--
+Viet Hoang Luu (@vi3tL0u1s)
+--FILE--
+<?php
+
+#[AllowDynamicProperties]
+class Trigger {
+    public $a = 'x';
+    public $b = 'x';
+    public $c = 'x';
+    public $d = 'x';
+    public $e = 'x';
+    public $f = 'x';
+    public string $trigger {
+      get {
+        return 'trigger';
+      }
+    }
+}
+
+$obj = new Trigger();
+// Add 2 dynamic props
+$obj->g = $obj->h = 'x';
+var_export($obj);
+
+?>
+--EXPECT--
+\Trigger::__set_state(array(
+   'a' => 'x',
+   'b' => 'x',
+   'c' => 'x',
+   'd' => 'x',
+   'e' => 'x',
+   'f' => 'x',
+   'trigger' => 'trigger',
+   'h' => 'x',
+   'g' => 'x',
+))
diff --git a/Zend/zend_property_hooks.c b/Zend/zend_property_hooks.c
index 01a8afb1693..57e22f23ad7 100644
--- a/Zend/zend_property_hooks.c
+++ b/Zend/zend_property_hooks.c
@@ -121,7 +121,7 @@ static zend_array *zho_build_properties_ex(zend_object *zobj, bool check_access,
 			if (Z_TYPE_P(prop_value) == IS_INDIRECT) {
 				continue;
 			}
-			zval *tmp = _zend_hash_append(properties, prop_name, prop_value);
+			zval *tmp = zend_hash_add_new(properties, prop_name, prop_value);
 			Z_TRY_ADDREF_P(tmp);
 		} ZEND_HASH_FOREACH_END();
 	}