[PHP-CVS] [php-src] master: Merge branch 'PHP-8.5'

[email protected] (Ilia Alshanetsky) Thu, 30 Jul 2026 12:49:18 +0000
Newsgroups php.cvs
Message-ID <[email protected]>
Author: Ilia Alshanetsky (iliaal)
Date: 2026-07-30T08:31:28-04:00

Commit: https://github.com/php/php-src/commit/4a42b033c2267758d810842c7050a2334d1d780e
Raw diff: https://github.com/php/php-src/commit/4a42b033c2267758d810842c7050a2334d1d780e.diff

Merge branch 'PHP-8.5'

* PHP-8.5:
  Free the hooked property value when json_encode() sees an exception

Changed paths:
  A  ext/json/tests/json_encode_hooked_property_throwing_getter.phpt
  M  ext/json/json_encoder.c


Diff:

diff --git a/ext/json/json_encoder.c b/ext/json/json_encoder.c
index 22af1c15a833..b8ae31040c8b 100644
--- a/ext/json/json_encoder.c
+++ b/ext/json/json_encoder.c
@@ -269,6 +269,7 @@ static zend_result php_json_encode_array(smart_str *buf, zval *val, int options,
 						if (EG(exception)) {
 							PHP_JSON_HASH_UNPROTECT_RECURSION(recursion_rc);
 							zend_release_properties(prop_ht);
+							zval_ptr_dtor(&tmp);
 							return FAILURE;
 						}
 					}
diff --git a/ext/json/tests/json_encode_hooked_property_throwing_getter.phpt b/ext/json/tests/json_encode_hooked_property_throwing_getter.phpt
new file mode 100644
index 000000000000..63fc8cf42c0e
--- /dev/null
+++ b/ext/json/tests/json_encode_hooked_property_throwing_getter.phpt
@@ -0,0 +1,44 @@
+--TEST--
+json_encode() releases the hooked property value when the get hook throws
+--FILE--
+<?php
+
+class Value
+{
+    public function __destruct()
+    {
+        echo "Value::__destruct\n";
+    }
+}
+
+class ThrowOnFree
+{
+    public function __destruct()
+    {
+        throw new Exception('thrown while freeing the get hook frame');
+    }
+}
+
+class Container
+{
+    public $hooked {
+        get {
+            $local = new ThrowOnFree();
+            return new Value();
+        }
+    }
+}
+
+try {
+    json_encode(new Container());
+} catch (Throwable $e) {
+    echo $e::class, ': ', $e->getMessage(), "\n";
+}
+
+echo "done\n";
+
+?>
+--EXPECT--
+Value::__destruct
+Exception: thrown while freeing the get hook frame
+done