From: Nikita Popov Date: Wed, 25 Nov 2020 16:04:07 +0000 (+0100) Subject: Fix unserialization ref source management, again X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f5b93626a6c7326b5e46626a701ac843eea1674b;p=php Fix unserialization ref source management, again Handle one case the previous patch did not account for: If unserialization of data fails, we should still register a ref source. Also add an extra test for a reference between two typed properties, as this used to be handled incorrectly earlier. --- diff --git a/ext/standard/tests/serialize/typed_property_ref_assignment_failure.phpt b/ext/standard/tests/serialize/typed_property_ref_assignment_failure.phpt index 2e4b576cc2..7ee35e8b69 100644 --- a/ext/standard/tests/serialize/typed_property_ref_assignment_failure.phpt +++ b/ext/standard/tests/serialize/typed_property_ref_assignment_failure.phpt @@ -16,6 +16,14 @@ try { echo $e->getMessage(), "\n"; } +$s = <<<'STR' +O:4:"Test":1:{s:4:"prop";a:1:{i:0;R:2; +STR; +var_dump(unserialize($s)); + ?> ---EXPECT-- +--EXPECTF-- Cannot assign stdClass to property Test::$prop of type int + +Notice: unserialize(): Error at offset 38 of 38 bytes in %s on line %d +bool(false) diff --git a/ext/standard/tests/serialize/typed_property_refs.phpt b/ext/standard/tests/serialize/typed_property_refs.phpt index 3c8096a392..9c71d460c2 100644 --- a/ext/standard/tests/serialize/typed_property_refs.phpt +++ b/ext/standard/tests/serialize/typed_property_refs.phpt @@ -13,6 +13,11 @@ class B { public int $b; } +class E { + public $a; + public int $b; +} + class C { public int $a; public string $b; @@ -25,6 +30,7 @@ class D { var_dump(unserialize('O:1:"A":2:{s:1:"a";i:1;s:1:"b";R:2;}')); var_dump(unserialize('O:1:"B":2:{s:1:"a";i:1;s:1:"b";R:2;}')); +var_dump(unserialize('O:1:"E":2:{s:1:"a";i:1;s:1:"b";R:2;}')); try { var_dump(unserialize('O:1:"A":2:{s:1:"a";N;s:1:"b";R:2;}')); @@ -66,6 +72,12 @@ object(B)#1 (2) { ["b"]=> &int(1) } +object(E)#1 (2) { + ["a"]=> + &int(1) + ["b"]=> + &int(1) +} Cannot assign null to property A::$a of type int Cannot assign null to property B::$b of type int Cannot assign int to property C::$b of type string diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 0143d94c70..d684163e83 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -578,6 +578,11 @@ string_key: } if (!php_var_unserialize_internal(data, p, max, var_hash, 0)) { + if (info && Z_ISREF_P(data)) { + /* Add type source even if we failed to unserialize. + * The data is still stored in the property. */ + ZEND_REF_ADD_TYPE_SOURCE(Z_REF_P(data), info); + } zval_ptr_dtor(&key); goto failure; }