]> granicus.if.org Git - php/commitdiff
Don't use unmangled name if property not found
authorNikita Popov <nikita.ppv@gmail.com>
Thu, 18 Feb 2021 09:16:40 +0000 (10:16 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Thu, 18 Feb 2021 09:17:23 +0000 (10:17 +0100)
This restores the previous behavior for this case. We'll continue
to use the mangled name, even if it does not correspond to a
declared property.

This also fixes an assertion failure for the case of property
overwrite, as the add_new was not guaranteed to be "new" previously.

Fixes oss-fuzz #31045.

ext/standard/tests/serialize/unserialize_overwrite_undeclared_protected.phpt [new file with mode: 0644]
ext/standard/var_unserializer.re

diff --git a/ext/standard/tests/serialize/unserialize_overwrite_undeclared_protected.phpt b/ext/standard/tests/serialize/unserialize_overwrite_undeclared_protected.phpt
new file mode 100644 (file)
index 0000000..b442c92
--- /dev/null
@@ -0,0 +1,21 @@
+--TEST--
+Overwriting an undeclared property with protected mangling
+--FILE--
+<?php
+class Test {
+    // We need at least one declared property, even though we don't use it.
+    public $foo;
+}
+
+$str = <<<STR
+O:4:"Test":2:{s:4:"\0*\0x";N;s:4:"\0*\0x";N;}
+STR;
+var_dump(unserialize($str));
+?>
+--EXPECT--
+object(Test)#1 (2) {
+  ["foo"]=>
+  NULL
+  ["x":protected]=>
+  NULL
+}
index 5f3b81a77df22cbf4d26f62ef877ae898c131ad3..56fe1fc784775d4d3812d3710dfa43e125f2aa97 100644 (file)
@@ -548,18 +548,12 @@ static int is_property_visibility_changed(zend_class_entry *ce, zval *key)
                } else {
                        if (!strcmp(unmangled_class, "*")
                         || !strcasecmp(unmangled_class, ZSTR_VAL(ce->name))) {
-                               zend_string *unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
-
-                               existing_propinfo = zend_hash_find_ptr(&ce->properties_info, unmangled);
+                               existing_propinfo = zend_hash_str_find_ptr(
+                                       &ce->properties_info, unmangled_prop, unmangled_prop_len);
                                if (existing_propinfo != NULL) {
-                                       zend_string_release_ex(unmangled, 0);
                                        zval_ptr_dtor_str(key);
                                        ZVAL_STR_COPY(key, existing_propinfo->name);
                                        return 1;
-                               } else {
-                                       zval_ptr_dtor_str(key);
-                                       ZVAL_STR(key, unmangled);
-                                       return 0;
                                }
                        }
                }