]> granicus.if.org Git - php/commitdiff
Fix unserialization ref source management, again
authorNikita Popov <nikita.ppv@gmail.com>
Wed, 25 Nov 2020 16:04:07 +0000 (17:04 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Wed, 25 Nov 2020 16:04:07 +0000 (17:04 +0100)
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.

ext/standard/tests/serialize/typed_property_ref_assignment_failure.phpt
ext/standard/tests/serialize/typed_property_refs.phpt
ext/standard/var_unserializer.re

index 2e4b576cc233ea621ab2be16ab9fc03486c40e4c..7ee35e8b691822b69de72a68a9aa4cc8913c7cef 100644 (file)
@@ -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)
index 3c8096a3928e8930f1a2d4ace3e17df2f3e11503..9c71d460c2cc49fe5c0e39a1b9bbdeb5ff1e233e 100644 (file)
@@ -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
index 0143d94c704805dbd79f12c514bcb758b486ac0f..d684163e83833644bd2c71a05a4197eb6d18472c 100644 (file)
@@ -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;
                }