From 7c111e1e803736d9cebc800577483bfa872b3c71 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 29 Aug 2008 14:59:41 +0000 Subject: [PATCH] Fixed bug #45706 (Unserialization of classes derived from ArrayIterator fails) --- ext/standard/tests/serialize/bug45706.phpt | 28 +++++++ .../serialize/serialization_objects_009.phpt | 16 ++-- ext/standard/var_unserializer.c | 83 ++++++++++--------- ext/standard/var_unserializer.re | 17 ++-- 4 files changed, 89 insertions(+), 55 deletions(-) create mode 100644 ext/standard/tests/serialize/bug45706.phpt diff --git a/ext/standard/tests/serialize/bug45706.phpt b/ext/standard/tests/serialize/bug45706.phpt new file mode 100644 index 0000000000..1a3854d69a --- /dev/null +++ b/ext/standard/tests/serialize/bug45706.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #45706 Unserialization of classes derived from ArrayIterator fails +--FILE-- + + 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" + } +} diff --git a/ext/standard/tests/serialize/serialization_objects_009.phpt b/ext/standard/tests/serialize/serialization_objects_009.phpt index 41e7ce5880..a4aa97e574 100644 --- a/ext/standard/tests/serialize/serialization_objects_009.phpt +++ b/ext/standard/tests/serialize/serialization_objects_009.phpt @@ -24,13 +24,13 @@ echo "Done"; ?> --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 diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index fc60ed47e2..769bdba258 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -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" /* +----------------------------------------------------------------------+ @@ -363,11 +363,6 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) 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 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) 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 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) 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 @@ yy2: 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 @@ yy14: 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 @@ yy21: 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 @@ yy21: *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 @@ yy21: 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 @@ yy28: 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 @@ yy28: 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 @@ yy35: 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 @@ yy35: 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 @@ yy42: 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 @@ yy42: 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 @@ yy49: 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 @@ yy49: 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 @@ yy56: 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 @@ yy56: 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 @@ yy69: } 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 @@ yy81: 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 @@ yy81: 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 @@ yy87: 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 @@ yy91: 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 @@ yy99: 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 @@ yy99: 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 @@ yy105: 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 @@ yy105: 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; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 1cbcbdf7b1..30592f8717 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -367,11 +367,6 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) 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 @@ static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce) 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 @@ object ":" uiv ":" ["] { *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); -- 2.40.0