[php-src] PHP-8.5: zend_objects: Readonly properties must be re-locked after clone-with (#22654)

NickSdot via GitHub <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: NickSdot (NickSdot)
Committer: GitHub (web-flow)
Pusher: TimWolla
Date: 2026-07-13T08:52:27+02:00

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

zend_objects: Readonly properties must be re-locked after clone-with (#22654)

Changed paths:
  A  Zend/tests/clone/clone_with_014.phpt
  M  NEWS
  M  Zend/zend_objects.c


Diff:

diff --git a/NEWS b/NEWS
index 46f23c3aa6d1..ed10d3bf2595 100644
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,8 @@ PHP                                                                        NEWS
     containing NUL). (iliaal)
   . Fixed bug GH-22206 (missing return in global register detection).
     (P3p111n0)
+  . Lock unmodified readonly properties for modification after clone-with.
+    (NickSdot)
 
 - Calendar:
   . Fixed bug GH-22602 (gregoriantojd() and juliantojd() integer overflow with
diff --git a/Zend/tests/clone/clone_with_014.phpt b/Zend/tests/clone/clone_with_014.phpt
new file mode 100644
index 000000000000..bfbee40e163c
--- /dev/null
+++ b/Zend/tests/clone/clone_with_014.phpt
@@ -0,0 +1,41 @@
+--TEST--
+Properties are still readonly after clone-with
+--FILE--
+<?php
+
+readonly class Test {
+    public public(set) int $a;
+    public public(set) int $b;
+
+    public function __construct() {
+        $this->a = 1;
+        $this->b = 2;
+    }
+}
+
+$test = clone(new Test(), ['a' => 3]);
+var_dump($test);
+
+try {
+    $test->b = 4;
+} catch (Error $e) {
+    echo $e::class, ": ", $e->getMessage(), PHP_EOL;
+}
+
+var_dump($test);
+
+?>
+--EXPECT--
+object(Test)#2 (2) {
+  ["a"]=>
+  int(3)
+  ["b"]=>
+  int(2)
+}
+Error: Cannot modify readonly property Test::$b
+object(Test)#2 (2) {
+  ["a"]=>
+  int(3)
+  ["b"]=>
+  int(2)
+}
diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c
index 6f6a82638944..d92d54d3f4a4 100644
--- a/Zend/zend_objects.c
+++ b/Zend/zend_objects.c
@@ -322,6 +322,14 @@ ZEND_API zend_object *zend_objects_clone_obj_with(zend_object *old_object, const
 		} ZEND_HASH_FOREACH_END();
 
 		EG(fake_scope) = old_scope;
+
+		/* Lock readonly properties once more. */
+		if (ZEND_CLASS_HAS_READONLY_PROPS(new_object->ce)) {
+			for (uint32_t i = 0; i < new_object->ce->default_properties_count; i++) {
+				zval* prop = OBJ_PROP_NUM(new_object, i);
+				Z_PROP_FLAG_P(prop) &= ~IS_PROP_REINITABLE;
+			}
+		}
 	}
 
 	return new_object;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.