summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2020-11-25 17:04:07 +0100
committerNikita Popov <nikita.ppv@gmail.com>2020-11-25 17:04:07 +0100
commitf5b93626a6c7326b5e46626a701ac843eea1674b (patch)
treec6e0867f52cf69a2e28756ec593972dbfbd470e6
parent518eb0ca2b8ea7fecb7a8db793de06cce568d8ce (diff)
downloadphp-git-f5b93626a6c7326b5e46626a701ac843eea1674b.tar.gz
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.
-rw-r--r--ext/standard/tests/serialize/typed_property_ref_assignment_failure.phpt10
-rw-r--r--ext/standard/tests/serialize/typed_property_refs.phpt12
-rw-r--r--ext/standard/var_unserializer.re5
3 files changed, 26 insertions, 1 deletions
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;
}