summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ext/standard/tests/serialize/typed_property_ref_overwrite.phpt19
-rw-r--r--ext/standard/var_unserializer.re4
2 files changed, 23 insertions, 0 deletions
diff --git a/ext/standard/tests/serialize/typed_property_ref_overwrite.phpt b/ext/standard/tests/serialize/typed_property_ref_overwrite.phpt
new file mode 100644
index 0000000000..148c66b76c
--- /dev/null
+++ b/ext/standard/tests/serialize/typed_property_ref_overwrite.phpt
@@ -0,0 +1,19 @@
+--TEST--
+Overwriting a typed property reference
+--FILE--
+<?php
+
+class Test {
+ public ?object $prop;
+}
+$s = <<<'STR'
+O:4:"Test":2:{s:4:"prop";R:1;s:4:"prop";N;}}
+STR;
+var_dump(unserialize($s));
+
+?>
+--EXPECT--
+object(Test)#1 (1) {
+ ["prop"]=>
+ NULL
+}
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index d684163e83..04f02cd762 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -556,6 +556,10 @@ string_key:
/* This is a property with a declaration */
old_data = Z_INDIRECT_P(old_data);
info = zend_get_typed_property_info_for_slot(obj, old_data);
+ if (Z_ISREF_P(old_data)) {
+ /* If the value is overwritten, remove old type source from ref. */
+ ZEND_REF_DEL_TYPE_SOURCE(Z_REF_P(old_data), info);
+ }
var_push_dtor(var_hash, old_data);
Z_TRY_DELREF_P(old_data);
ZVAL_COPY_VALUE(old_data, &d);