diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-30 14:23:17 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2020-11-30 14:23:54 +0100 |
commit | ed9532cff087a2b5db418b627471776897abe663 (patch) | |
tree | 12f842d04196ca31f981edff63ae3562cb9d9a5c | |
parent | 666833b238759e4f08bfa138f61c8038efb738b5 (diff) | |
download | php-git-ed9532cff087a2b5db418b627471776897abe663.tar.gz |
Fix another ref source management bug in unserialize
When we overwrite an existing property during unserialization,
we also have to drop the ref source from it.
-rw-r--r-- | ext/standard/tests/serialize/typed_property_ref_overwrite.phpt | 19 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 4 |
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); |