dmitry Fri Aug 29 14:59:41 2008 UTC Modified files: /php-src/ext/standard var_unserializer.c var_unserializer.re /php-src/ext/standard/tests/serialize bug45706.phpt serialization_objects_009.phpt Log: Fixed bug #45706 (Unserialization of classes derived from ArrayIterator fails)
http://cvs.php.net/viewvc.cgi/php-src/ext/standard/var_unserializer.c?r1=1.95&r2=1.96&diff_format=u Index: php-src/ext/standard/var_unserializer.c diff -u php-src/ext/standard/var_unserializer.c:1.95 php-src/ext/standard/var_unserializer.c:1.96 --- php-src/ext/standard/var_unserializer.c:1.95 Tue May 27 11:27:58 2008 +++ php-src/ext/standard/var_unserializer.c Fri Aug 29 14:59:41 2008 @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Tue May 27 06:15:01 2008 */ +/* Generated by re2c 0.13.5 on Fri Aug 29 18:45:19 2008 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.c,v 1.95 2008/05/27 11:27:58 mattwil Exp $ */ +/* $Id: var_unserializer.c,v 1.96 2008/08/29 14:59:41 dmitry Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -363,11 +363,6 @@ zstr buf; size_t buf_len; - if (ce->unserialize == NULL) { - zend_error(E_WARNING, "Class %v has no unserializer", ce->name); - return 0; - } - datalen = parse_iv2((*p) + 2, p); switch((*p)[1]) { @@ -400,7 +395,10 @@ buf_len = datalen; (*p) += datalen; } - if (ce->unserialize(rval, ce, type, buf, buf_len, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) { + if (ce->unserialize == NULL) { + zend_error(E_WARNING, "Class %v has no unserializer", ce->name); + object_init_ex(*rval, ce); + } else if (ce->unserialize(rval, ce, type, buf, buf_len, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) { if (type == IS_UNICODE) { efree(buf.v); } @@ -463,7 +461,7 @@ start = cursor; -#line 467 "ext/standard/var_unserializer.c" +#line 465 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -524,9 +522,9 @@ yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy103; yy3: -#line 791 "ext/standard/var_unserializer.re" +#line 794 "ext/standard/var_unserializer.re" { return 0; } -#line 530 "ext/standard/var_unserializer.c" +#line 528 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy97; @@ -573,13 +571,13 @@ goto yy3; yy15: ++YYCURSOR; -#line 785 "ext/standard/var_unserializer.re" +#line 788 "ext/standard/var_unserializer.re" { /* this is the case where we have less data than planned */ php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data"); return 0; /* not sure if it should be 0 or 1 here? */ } -#line 583 "ext/standard/var_unserializer.c" +#line 581 "ext/standard/var_unserializer.c" yy17: yych = *++YYCURSOR; goto yy3; @@ -609,7 +607,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy19; ++YYCURSOR; -#line 672 "ext/standard/var_unserializer.re" +#line 670 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -709,8 +707,13 @@ *p = YYCURSOR; if (custom_object) { + int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); + + if (ret && incomplete_class) { + php_store_class_name(*rval, class_name, len2); + } efree(class_name.v); - return object_custom(UNSERIALIZE_PASSTHRU, ce); + return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); @@ -722,7 +725,7 @@ return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 726 "ext/standard/var_unserializer.c" +#line 729 "ext/standard/var_unserializer.c" yy26: yych = *++YYCURSOR; if (yych <= ',') { @@ -747,7 +750,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy19; ++YYCURSOR; -#line 664 "ext/standard/var_unserializer.re" +#line 662 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); @@ -755,7 +758,7 @@ return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 759 "ext/standard/var_unserializer.c" +#line 762 "ext/standard/var_unserializer.c" yy33: yych = *++YYCURSOR; if (yych == '+') goto yy34; @@ -776,7 +779,7 @@ yych = *++YYCURSOR; if (yych != '{') goto yy19; ++YYCURSOR; -#line 644 "ext/standard/var_unserializer.re" +#line 642 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -796,7 +799,7 @@ return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 800 "ext/standard/var_unserializer.c" +#line 803 "ext/standard/var_unserializer.c" yy40: yych = *++YYCURSOR; if (yych == '+') goto yy41; @@ -817,7 +820,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy19; ++YYCURSOR; -#line 615 "ext/standard/var_unserializer.re" +#line 613 "ext/standard/var_unserializer.re" { size_t len, maxlen; UChar *ustr; @@ -846,7 +849,7 @@ ZVAL_UNICODEL(*rval, ustr, len, 0); return 1; } -#line 850 "ext/standard/var_unserializer.c" +#line 853 "ext/standard/var_unserializer.c" yy47: yych = *++YYCURSOR; if (yych == '+') goto yy48; @@ -867,7 +870,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy19; ++YYCURSOR; -#line 586 "ext/standard/var_unserializer.re" +#line 584 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -896,7 +899,7 @@ ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 900 "ext/standard/var_unserializer.c" +#line 903 "ext/standard/var_unserializer.c" yy54: yych = *++YYCURSOR; if (yych == '+') goto yy55; @@ -917,7 +920,7 @@ yych = *++YYCURSOR; if (yych != '"') goto yy19; ++YYCURSOR; -#line 558 "ext/standard/var_unserializer.re" +#line 556 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -945,7 +948,7 @@ ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 949 "ext/standard/var_unserializer.c" +#line 952 "ext/standard/var_unserializer.c" yy61: yych = *++YYCURSOR; if (yych <= '/') { @@ -1033,14 +1036,14 @@ } yy71: ++YYCURSOR; -#line 551 "ext/standard/var_unserializer.re" +#line 549 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 1044 "ext/standard/var_unserializer.c" +#line 1047 "ext/standard/var_unserializer.c" yy73: yych = *++YYCURSOR; if (yych <= ',') { @@ -1099,7 +1102,7 @@ yych = *++YYCURSOR; if (yych != ';') goto yy19; ++YYCURSOR; -#line 536 "ext/standard/var_unserializer.re" +#line 534 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -1114,7 +1117,7 @@ return 1; } -#line 1118 "ext/standard/var_unserializer.c" +#line 1121 "ext/standard/var_unserializer.c" yy84: yych = *++YYCURSOR; if (yych == 'N') goto yy81; @@ -1141,14 +1144,14 @@ if (yych <= '9') goto yy87; if (yych != ';') goto yy19; ++YYCURSOR; -#line 529 "ext/standard/var_unserializer.re" +#line 527 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1152 "ext/standard/var_unserializer.c" +#line 1155 "ext/standard/var_unserializer.c" yy91: yych = *++YYCURSOR; if (yych <= '/') goto yy19; @@ -1156,24 +1159,24 @@ yych = *++YYCURSOR; if (yych != ';') goto yy19; ++YYCURSOR; -#line 522 "ext/standard/var_unserializer.re" +#line 520 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1167 "ext/standard/var_unserializer.c" +#line 1170 "ext/standard/var_unserializer.c" yy95: ++YYCURSOR; -#line 515 "ext/standard/var_unserializer.re" +#line 513 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1177 "ext/standard/var_unserializer.c" +#line 1180 "ext/standard/var_unserializer.c" yy97: yych = *++YYCURSOR; if (yych <= ',') { @@ -1196,7 +1199,7 @@ if (yych <= '9') goto yy99; if (yych != ';') goto yy19; ++YYCURSOR; -#line 492 "ext/standard/var_unserializer.re" +#line 490 "ext/standard/var_unserializer.re" { long id; @@ -1219,7 +1222,7 @@ return 1; } -#line 1223 "ext/standard/var_unserializer.c" +#line 1226 "ext/standard/var_unserializer.c" yy103: yych = *++YYCURSOR; if (yych <= ',') { @@ -1242,7 +1245,7 @@ if (yych <= '9') goto yy105; if (yych != ';') goto yy19; ++YYCURSOR; -#line 471 "ext/standard/var_unserializer.re" +#line 469 "ext/standard/var_unserializer.re" { long id; @@ -1263,9 +1266,9 @@ return 1; } -#line 1267 "ext/standard/var_unserializer.c" +#line 1270 "ext/standard/var_unserializer.c" } -#line 793 "ext/standard/var_unserializer.re" +#line 796 "ext/standard/var_unserializer.re" return 0; http://cvs.php.net/viewvc.cgi/php-src/ext/standard/var_unserializer.re?r1=1.74&r2=1.75&diff_format=u Index: php-src/ext/standard/var_unserializer.re diff -u php-src/ext/standard/var_unserializer.re:1.74 php-src/ext/standard/var_unserializer.re:1.75 --- php-src/ext/standard/var_unserializer.re:1.74 Tue May 27 10:28:25 2008 +++ php-src/ext/standard/var_unserializer.re Fri Aug 29 14:59:41 2008 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.re,v 1.74 2008/05/27 10:28:25 mattwil Exp $ */ +/* $Id: var_unserializer.re,v 1.75 2008/08/29 14:59:41 dmitry Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -367,11 +367,6 @@ zstr buf; size_t buf_len; - if (ce->unserialize == NULL) { - zend_error(E_WARNING, "Class %v has no unserializer", ce->name); - return 0; - } - datalen = parse_iv2((*p) + 2, p); switch((*p)[1]) { @@ -404,7 +399,10 @@ buf_len = datalen; (*p) += datalen; } - if (ce->unserialize(rval, ce, type, buf, buf_len, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) { + if (ce->unserialize == NULL) { + zend_error(E_WARNING, "Class %v has no unserializer", ce->name); + object_init_ex(*rval, ce); + } else if (ce->unserialize(rval, ce, type, buf, buf_len, (zend_unserialize_data *)var_hash TSRMLS_CC) != SUCCESS) { if (type == IS_UNICODE) { efree(buf.v); } @@ -768,8 +766,13 @@ *p = YYCURSOR; if (custom_object) { + int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); + + if (ret && incomplete_class) { + php_store_class_name(*rval, class_name, len2); + } efree(class_name.v); - return object_custom(UNSERIALIZE_PASSTHRU, ce); + return ret; } elements = object_common1(UNSERIALIZE_PASSTHRU, ce); http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/serialize/bug45706.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/standard/tests/serialize/bug45706.phpt diff -u /dev/null php-src/ext/standard/tests/serialize/bug45706.phpt:1.2 --- /dev/null Fri Aug 29 14:59:41 2008 +++ php-src/ext/standard/tests/serialize/bug45706.phpt Fri Aug 29 14:59:41 2008 @@ -0,0 +1,28 @@ +--TEST-- +Bug #45706 Unserialization of classes derived from ArrayIterator fails +--FILE-- +<?php +class Foo1 extends ArrayIterator +{ +} +class Foo2 { +} +$x = array(new Foo1(),new Foo2); +$s = serialize($x); +$s = str_replace("Foo", "Bar", $s); +$y = unserialize($s); +var_dump($y); +--EXPECTF-- +Warning: Class __PHP_Incomplete_Class has no unserializer in %sbug45706.php on line %d +array(2) { + [0]=> + object(__PHP_Incomplete_Class)#%d (1) { + [u"__PHP_Incomplete_Class_Name"]=> + unicode(4) "Bar1" + } + [1]=> + object(__PHP_Incomplete_Class)#%d (1) { + [u"__PHP_Incomplete_Class_Name"]=> + unicode(4) "Bar2" + } +} http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/serialize/serialization_objects_009.phpt?r1=1.3&r2=1.4&diff_format=u Index: php-src/ext/standard/tests/serialize/serialization_objects_009.phpt diff -u php-src/ext/standard/tests/serialize/serialization_objects_009.phpt:1.3 php-src/ext/standard/tests/serialize/serialization_objects_009.phpt:1.4 --- php-src/ext/standard/tests/serialize/serialization_objects_009.phpt:1.3 Tue May 27 07:45:40 2008 +++ php-src/ext/standard/tests/serialize/serialization_objects_009.phpt Fri Aug 29 14:59:41 2008 @@ -24,13 +24,13 @@ ?> --EXPECTF-- -Warning: Class __PHP_Incomplete_Class has no unserializer in %s on line 14 +Warning: Class __PHP_Incomplete_Class has no unserializer in %sserialization_objects_009.php on line %d -Notice: unserialize(): Error at offset 6 of 18 bytes in %s on line 14 - -Warning: Class C has no unserializer in %s on line 16 - -Notice: unserialize(): Error at offset 6 of 18 bytes in %s on line 16 -bool(false) -bool(false) +Warning: Class C has no unserializer in %sserialization_objects_009.php on line %d +object(__PHP_Incomplete_Class)#%d (1) { + [u"__PHP_Incomplete_Class_Name"]=> + unicode(1) "C" +} +object(C)#%d (0) { +} Done
-- PHP CVS Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php