Re: com php-src: Fix #49649 - Handle property visibility changes on unserialization: NEWS ext/standard/tests/serialize/bug49649.phpt
ext/standard/tests/serialize/bug49649_1.phpt ext/standard/tests/serialize/bug49649_2.phpt ext/standard/var_unser

From: Date: Mon, 10 Jul 2017 09:55:35 +0000
Subject: Re: com php-src: Fix #49649 - Handle property visibility changes on unserialization: NEWS ext/standard/tests/serialize/bug49649.phpt
ext/standard/tests/serialize/bug49649_1.phpt ext/standard/tests/serialize/bug49649_2.phpt ext/standard/var_unser
References: 1 2  Groups: php.cvs 
Request: Send a blank email to php-cvs+get-98493@lists.php.net to get a copy of this message
ACK, someone will look at it today ... Cheers Joe On Mon, Jul 10, 2017 at 10:34 AM, Dmitry Stogov <dmitry@zend.com> wrote: > This caused memory leak in Zend/tests/bug30791.phpt > > > ==13493== 20 bytes in 1 blocks are definitely lost in loss record 64 of 157 > ==13493== at 0x402C289: malloc (vg_replace_malloc.c:299) > ==13493== by 0x864C1C8: __zend_malloc (zend_alloc.c:2811) > ==13493== by 0x864B796: _emalloc (zend_alloc.c:2413) > ==13493== by 0x8550CE1: zend_string_alloc (zend_string.h:134) > ==13493== by 0x8550DDD: zend_string_init (zend_string.h:170) > ==13493== by 0x8551CE1: process_nested_data (var_unserializer.re:442) > ==13493== by 0x8552371: object_common2 (var_unserializer.re:600) > ==13493== by 0x855300F: php_var_unserialize_internal ( > var_unserializer.re:1045) > ==13493== by 0x85524B1: php_var_unserialize (var_unserializer.re:628) > ==13493== by 0x85435BC: zif_unserialize (var.c:1100) > ==13493== by 0x86C5BC9: ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER > (zend_vm_execute.h:617) > ==13493== by 0x8732538: execute_ex (zend_vm_execute.h:59096) > > > Thanks. Dmitry. > ------------------------------ > *From:* Joe Watkins <krakjoe@php.net> > *Sent:* Monday, July 10, 2017 9:27:09 AM > *To:* php-cvs@lists.php.net > *Subject:* [PHP-CVS] com php-src: Fix #49649 - Handle property visibility > changes on unserialization: NEWS ext/standard/tests/serialize/bug49649.phpt > ext/standard/tests/serialize/bug49649_1.phpt ext/standard/tests/serialize/bug49649_2.phpt > ext/standard/var_unseri... > > Commit: 7cb5bdf64a95bd70623d33d6ea122c13b01113bd > Author: Pedro Magalhães <mail@pmmaga.net> Fri, 21 Apr 2017 > 19:37:27 +0200 > Committer: Joe Watkins <krakjoe@php.net> Mon, 10 Jul 2017 07:27:09 > +0100 > Parents: cfacf84dc19c9ef497a67d09c02e27408830baa8 > Branches: master > > Link: http://git.php.net/?p=php-src.git;a=commitdiff;h= > 7cb5bdf64a95bd70623d33d6ea122c13b01113bd > > Log: > Fix #49649 - Handle property visibility changes on unserialization > > Bugs: > https://bugs.php.net/49649 > > Changed paths: > M NEWS > A ext/standard/tests/serialize/bug49649.phpt > A ext/standard/tests/serialize/bug49649_1.phpt > A ext/standard/tests/serialize/bug49649_2.phpt > M ext/standard/var_unserializer.re > > > Diff: > diff --git a/NEWS b/NEWS > index d9c1e5b..c88a6c5 100644 > --- a/NEWS > +++ b/NEWS > @@ -10,6 +10,8 @@ PHP > NEWS > . Fixed bug #74819 (wddx_deserialize() heap out-of-bound read via > php_parse_date()). (Derick) > . Fixed bug #74878 (Data race in ZTS builds). (Nikita) > + . Fixed bug #49649 (unserialize() doesn't handle changes in property > + visibility). (pmmaga) > > - Date: > . Fixed bug #74852 (property_exists returns true on unknown > DateInterval > diff --git a/ext/standard/tests/serialize/bug49649.phpt > b/ext/standard/tests/serialize/bug49649.phpt > new file mode 100644 > index 0000000..2e0a505 > --- /dev/null > +++ b/ext/standard/tests/serialize/bug49649.phpt > @@ -0,0 +1,45 @@ > +--TEST-- > +Bug #49649 (unserialize() doesn't handle changes in property visibility) > - to public > +--FILE-- > +<?php > + > +/** > + *class Foo > + *{ > + * private $private = 1; > + * > + * protected $protected = 2; > + * > + * public $public = 3; > + * > + * public $notThere = 'old'; > + * } > + * > + * echo base64_encode(serialize(new Foo())); > + * > + * The class above represents the serialized, base64_encoded string below. > +*/ > +$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb2 > 8AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicH > VibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30'; > + > +class Foo > +{ > + public $public = null; > + > + public $protected = null; > + > + public $private = null; > +} > + > +$class = unserialize(base64_decode($serialized)); > +var_dump($class); > +--EXPECT-- > +object(Foo)#1 (4) { > + ["public"]=> > + int(3) > + ["protected"]=> > + int(2) > + ["private"]=> > + int(1) > + ["notThere"]=> > + string(3) "old" > +} > diff --git a/ext/standard/tests/serialize/bug49649_1.phpt > b/ext/standard/tests/serialize/bug49649_1.phpt > new file mode 100644 > index 0000000..1ca840a > --- /dev/null > +++ b/ext/standard/tests/serialize/bug49649_1.phpt > @@ -0,0 +1,45 @@ > +--TEST-- > +Bug #49649 (unserialize() doesn't handle changes in property visibility) > - to protected > +--FILE-- > +<?php > + > +/** > + *class Foo > + *{ > + * private $private = 1; > + * > + * protected $protected = 2; > + * > + * public $public = 3; > + * > + * public $notThere = 'old'; > + * } > + * > + * echo base64_encode(serialize(new Foo())); > + * > + * The class above represents the serialized, base64_encoded string below. > +*/ > +$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb2 > 8AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicH > VibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30'; > + > +class Foo > +{ > + protected $public = null; > + > + protected $protected = null; > + > + protected $private = null; > +} > + > +$class = unserialize(base64_decode($serialized)); > +var_dump($class); > +--EXPECT-- > +object(Foo)#1 (4) { > + ["public":protected]=> > + int(3) > + ["protected":protected]=> > + int(2) > + ["private":protected]=> > + int(1) > + ["notThere"]=> > + string(3) "old" > +} > diff --git a/ext/standard/tests/serialize/bug49649_2.phpt > b/ext/standard/tests/serialize/bug49649_2.phpt > new file mode 100644 > index 0000000..e9fe429 > --- /dev/null > +++ b/ext/standard/tests/serialize/bug49649_2.phpt > @@ -0,0 +1,45 @@ > +--TEST-- > +Bug #49649 (unserialize() doesn't handle changes in property visibility) > - to private > +--FILE-- > +<?php > + > +/** > + *class Foo > + *{ > + * private $private = 1; > + * > + * protected $protected = 2; > + * > + * public $public = 3; > + * > + * public $notThere = 'old'; > + * } > + * > + * echo base64_encode(serialize(new Foo())); > + * > + * The class above represents the serialized, base64_encoded string below. > +*/ > +$serialized = 'TzozOiJGb28iOjQ6e3M6MTI6IgBGb2 > 8AcHJpdmF0ZSI7aToxO3M6MTI6IgAqAHByb3RlY3RlZCI7aToyO3M6NjoicH > VibGljIjtpOjM7czo4OiJub3RUaGVyZSI7czozOiJvbGQiO30'; > + > +class Foo > +{ > + private $public = null; > + > + private $protected = null; > + > + private $private = null; > +} > + > +$class = unserialize(base64_decode($serialized)); > +var_dump($class); > +--EXPECT-- > +object(Foo)#1 (4) { > + ["public":"Foo":private]=> > + int(3) > + ["protected":"Foo":private]=> > + int(2) > + ["private":"Foo":private]=> > + int(1) > + ["notThere"]=> > + string(3) "old" > +} > diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_ > unserializer.re > index 185e62d..6e7f76f 100644 > --- a/ext/standard/var_unserializer.re > +++ b/ext/standard/var_unserializer.re > @@ -427,14 +427,58 @@ numeric_key: > } else { > if (EXPECTED(Z_TYPE(key) == IS_STRING)) { > string_key: > - if ((old_data = zend_hash_find(ht, > Z_STR(key))) != NULL) { > - if (Z_TYPE_P(old_data) == > IS_INDIRECT) { > - old_data = > Z_INDIRECT_P(old_data); > + { > + zend_property_info > *existing_propinfo; > + zend_string *new_key, *unmangled; > + const char *unmangled_class = > NULL; > + const char *unmangled_prop; > + size_t unmangled_prop_len; > + > + if > (UNEXPECTED(zend_unmangle_property_name_ex(Z_STR(key), > &unmangled_class, &unmangled_prop, &unmangled_prop_len) == FAILURE)) { > + zval_dtor(&key); > + return 0; > + } > + > + unmangled = > zend_string_init(unmangled_prop, unmangled_prop_len, 0); > + if (Z_TYPE_P(rval) == IS_OBJECT > + && > ((existing_propinfo = zend_hash_find_ptr(&Z_OBJCE_P(rval)->properties_info, > unmangled)) != NULL) > + && > (existing_propinfo->flags & ZEND_ACC_PPP_MASK)) { > + if > (existing_propinfo->flags & ZEND_ACC_PROTECTED) { > + new_key = > zend_mangle_property_name( > + "*", 1, > ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), Z_OBJCE_P(rval)->type & > ZEND_INTERNAL_CLASS); > + > zend_string_release(unmangled); > + } else if > (existing_propinfo->flags & ZEND_ACC_PRIVATE) { > + if > (unmangled_class != NULL && strcmp(unmangled_class, "*") != 0) { > + new_key = > zend_mangle_property_name( > + > unmangled_class, strlen(unmangled_class), > + > ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), > + > Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS); > + } else { > + new_key = > zend_mangle_property_name( > + > ZSTR_VAL(existing_propinfo->ce->name), ZSTR_LEN(existing_propinfo-> > ce->name), > + > ZSTR_VAL(unmangled), ZSTR_LEN(unmangled), > + > Z_OBJCE_P(rval)->type & ZEND_INTERNAL_CLASS); > + } > + > zend_string_release(unmangled); > + } else { > + > ZEND_ASSERT(existing_propinfo->flags & ZEND_ACC_PUBLIC); > + new_key = > unmangled; > + } > + > zend_string_release(Z_STR(key)); > + Z_STR(key) = new_key; > + } else { > + > zend_string_release(unmangled); > + } > + > + if ((old_data = > zend_hash_find(ht, Z_STR(key))) != NULL) { > + if (Z_TYPE_P(old_data) == > IS_INDIRECT) { > + old_data = > Z_INDIRECT_P(old_data); > + } > + var_push_dtor(var_hash, > old_data); > + data = > zend_hash_update_ind(ht, Z_STR(key), &d); > + } else { > + data = > zend_hash_add_new(ht, Z_STR(key), &d); > } > - var_push_dtor(var_hash, old_data); > - data = zend_hash_update_ind(ht, > Z_STR(key), &d); > - } else { > - data = zend_hash_add_new(ht, > Z_STR(key), &d); > } > } else if (Z_TYPE(key) == IS_LONG) { > /* object properties should include no > integers */ > > > -- > PHP CVS Mailing List (http://www.php.net/) > To unsubscribe, visit: http://www.php.net/unsub.php > >

« previous php.cvs (#98493) next »