Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions ext/standard/tests/serialize/bug76300.phpt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
--TEST--
Bug #76300: Unserialize of extended protected member broken
--FILE--
<?php
class Base {
private $id;
public function __construct($id)
{
$this->id = $id;
}
}
class Derived extends Base {
protected $id;
public function __construct($id)
{
parent::__construct($id + 20);
$this->id = $id;
}
}
$a = new Derived(44);
$s = serialize($a);
$u = unserialize($s);
print_r($u);
--EXPECT--
Derived Object
(
[id:protected] => 44
[id:Base:private] => 64
)
61 changes: 31 additions & 30 deletions ext/standard/var_unserializer.c
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,7 @@ static zend_always_inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTab

unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
if (Z_TYPE_P(rval) == IS_OBJECT
&& (unmangled_class == NULL || !strcmp(unmangled_class, "*") || !strcasecmp(unmangled_class, ZSTR_VAL(Z_OBJCE_P(rval)->name)))
&& ((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) {
Expand Down Expand Up @@ -644,7 +645,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
start = cursor;


#line 648 "ext/standard/var_unserializer.c"
#line 649 "ext/standard/var_unserializer.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
Expand Down Expand Up @@ -702,9 +703,9 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
yy2:
++YYCURSOR;
yy3:
#line 1035 "ext/standard/var_unserializer.re"
#line 1036 "ext/standard/var_unserializer.re"
{ return 0; }
#line 708 "ext/standard/var_unserializer.c"
#line 709 "ext/standard/var_unserializer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
if (yych == ':') goto yy17;
Expand Down Expand Up @@ -751,13 +752,13 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
goto yy3;
yy15:
++YYCURSOR;
#line 1029 "ext/standard/var_unserializer.re"
#line 1030 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
return 0; /* not sure if it should be 0 or 1 here? */
}
#line 761 "ext/standard/var_unserializer.c"
#line 762 "ext/standard/var_unserializer.c"
yy17:
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
Expand All @@ -768,13 +769,13 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
goto yy3;
yy19:
++YYCURSOR;
#line 701 "ext/standard/var_unserializer.re"
#line 702 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
ZVAL_NULL(rval);
return 1;
}
#line 778 "ext/standard/var_unserializer.c"
#line 779 "ext/standard/var_unserializer.c"
yy21:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
Expand Down Expand Up @@ -973,7 +974,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
goto yy18;
yy56:
++YYCURSOR;
#line 652 "ext/standard/var_unserializer.re"
#line 653 "ext/standard/var_unserializer.re"
{
zend_long id;

Expand All @@ -998,7 +999,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return 1;
}
#line 1002 "ext/standard/var_unserializer.c"
#line 1003 "ext/standard/var_unserializer.c"
yy58:
yych = *++YYCURSOR;
if (yych == '"') goto yy77;
Expand All @@ -1009,13 +1010,13 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
goto yy18;
yy60:
++YYCURSOR;
#line 707 "ext/standard/var_unserializer.re"
#line 708 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
ZVAL_BOOL(rval, parse_iv(start + 2));
return 1;
}
#line 1019 "ext/standard/var_unserializer.c"
#line 1020 "ext/standard/var_unserializer.c"
yy62:
++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
Expand All @@ -1035,7 +1036,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
}
yy64:
++YYCURSOR;
#line 755 "ext/standard/var_unserializer.re"
#line 756 "ext/standard/var_unserializer.re"
{
#if SIZEOF_ZEND_LONG == 4
use_double:
Expand All @@ -1044,7 +1045,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
return 1;
}
#line 1048 "ext/standard/var_unserializer.c"
#line 1049 "ext/standard/var_unserializer.c"
yy66:
yych = *++YYCURSOR;
if (yych <= ',') {
Expand All @@ -1066,7 +1067,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
goto yy18;
yy69:
++YYCURSOR;
#line 713 "ext/standard/var_unserializer.re"
#line 714 "ext/standard/var_unserializer.re"
{
#if SIZEOF_ZEND_LONG == 4
int digits = YYCURSOR - start - 3;
Expand All @@ -1092,14 +1093,14 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_LONG(rval, parse_iv(start + 2));
return 1;
}
#line 1096 "ext/standard/var_unserializer.c"
#line 1097 "ext/standard/var_unserializer.c"
yy71:
yych = *++YYCURSOR;
if (yych == '"') goto yy85;
goto yy18;
yy72:
++YYCURSOR;
#line 677 "ext/standard/var_unserializer.re"
#line 678 "ext/standard/var_unserializer.re"
{
zend_long id;

Expand All @@ -1123,14 +1124,14 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return 1;
}
#line 1127 "ext/standard/var_unserializer.c"
#line 1128 "ext/standard/var_unserializer.c"
yy74:
yych = *++YYCURSOR;
if (yych == '"') goto yy87;
goto yy18;
yy75:
++YYCURSOR;
#line 877 "ext/standard/var_unserializer.re"
#line 878 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
zend_long elements;
Expand Down Expand Up @@ -1282,10 +1283,10 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 1286 "ext/standard/var_unserializer.c"
#line 1287 "ext/standard/var_unserializer.c"
yy77:
++YYCURSOR;
#line 802 "ext/standard/var_unserializer.re"
#line 803 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
zend_string *str;
Expand Down Expand Up @@ -1319,10 +1320,10 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
ZVAL_STR(rval, str);
return 1;
}
#line 1323 "ext/standard/var_unserializer.c"
#line 1324 "ext/standard/var_unserializer.c"
yy79:
++YYCURSOR;
#line 836 "ext/standard/var_unserializer.re"
#line 837 "ext/standard/var_unserializer.re"
{
zend_long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
Expand Down Expand Up @@ -1352,7 +1353,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
#line 1356 "ext/standard/var_unserializer.c"
#line 1357 "ext/standard/var_unserializer.c"
yy81:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
Expand All @@ -1371,7 +1372,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
goto yy18;
yy85:
++YYCURSOR;
#line 866 "ext/standard/var_unserializer.re"
#line 867 "ext/standard/var_unserializer.re"
{
zend_long elements;
if (!var_hash) return 0;
Expand All @@ -1382,10 +1383,10 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
}
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
#line 1386 "ext/standard/var_unserializer.c"
#line 1387 "ext/standard/var_unserializer.c"
yy87:
++YYCURSOR;
#line 764 "ext/standard/var_unserializer.re"
#line 765 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
Expand Down Expand Up @@ -1423,10 +1424,10 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
}
return 1;
}
#line 1427 "ext/standard/var_unserializer.c"
#line 1428 "ext/standard/var_unserializer.c"
yy89:
++YYCURSOR;
#line 739 "ext/standard/var_unserializer.re"
#line 740 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;

Expand All @@ -1442,9 +1443,9 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)

return 1;
}
#line 1446 "ext/standard/var_unserializer.c"
#line 1447 "ext/standard/var_unserializer.c"
}
#line 1037 "ext/standard/var_unserializer.re"
#line 1038 "ext/standard/var_unserializer.re"


return 0;
Expand Down
1 change: 1 addition & 0 deletions ext/standard/var_unserializer.re
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ string_key:

unmangled = zend_string_init(unmangled_prop, unmangled_prop_len, 0);
if (Z_TYPE_P(rval) == IS_OBJECT
&& (unmangled_class == NULL || !strcmp(unmangled_class, "*") || !strcasecmp(unmangled_class, ZSTR_VAL(Z_OBJCE_P(rval)->name)))
&& ((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) {
Expand Down