diff options
author | Xinchen Hui <laruence@gmail.com> | 2015-11-24 11:42:43 +0800 |
---|---|---|
committer | Anatol Belski <ab@php.net> | 2015-11-25 03:17:17 +0100 |
commit | 22fdc95e5e2b67ed8bfd53f85c601a0d10f65ab5 (patch) | |
tree | f0b6c10f736265ee5869fe5f95ace9db7be53480 | |
parent | 57251853e788df4c75ba4727da51ef493def7fd9 (diff) | |
download | php-git-22fdc95e5e2b67ed8bfd53f85c601a0d10f65ab5.tar.gz |
Also fixed 'r'
-rw-r--r-- | ext/standard/tests/serialize/bug70963.phpt | 18 | ||||
-rw-r--r-- | ext/standard/var_unserializer.c | 92 | ||||
-rw-r--r-- | ext/standard/var_unserializer.re | 32 |
3 files changed, 91 insertions, 51 deletions
diff --git a/ext/standard/tests/serialize/bug70963.phpt b/ext/standard/tests/serialize/bug70963.phpt index 6802d99927..fc76771299 100644 --- a/ext/standard/tests/serialize/bug70963.phpt +++ b/ext/standard/tests/serialize/bug70963.phpt @@ -3,9 +3,25 @@ Bug #70963 (Unserialize shows UNKNOW in result) --FILE-- <?php var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".'trace";s:4:"test";}i:1;R:3;}')); +var_dump(unserialize('a:2:{i:0;O:9:"exception":1:{s:16:"'."\0".'Exception'."\0".'trace";s:4:"test";}i:1;r:3;}')); ?> --EXPECTF-- -array(2) { +array(1) { + [0]=> + object(Exception)#%d (5) { + ["message":protected]=> + string(0) "" + ["string":"Exception":private]=> + string(0) "" + ["code":protected]=> + int(0) + ["file":protected]=> + string(%d) "%s" + ["line":protected]=> + int(%d) + } +} +array(1) { [0]=> object(Exception)#%d (5) { ["message":protected]=> diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 3284ad31c3..5b127f283f 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -365,13 +365,22 @@ string_key: } } - zval_dtor(&key); - if (!php_var_unserialize_ex(data, p, max, var_hash, classes)) { + zval_dtor(&key); return 0; } - var_push_dtor(var_hash, data); + if (UNEXPECTED(Z_ISUNDEF_P(data))) { + if (Z_TYPE(key) == IS_LONG) { + zend_hash_index_del(ht, Z_LVAL(key)); + } else { + zend_hash_del_ind(ht, Z_STR(key)); + } + } else { + var_push_dtor(var_hash, data); + } + + zval_dtor(&key); if (elements && *(*p-1) != ';' && *(*p-1) != '}') { (*p)--; @@ -505,7 +514,7 @@ PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) start = cursor; -#line 509 "ext/standard/var_unserializer.c" +#line 518 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -565,9 +574,9 @@ yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 857 "ext/standard/var_unserializer.re" +#line 869 "ext/standard/var_unserializer.re" { return 0; } -#line 571 "ext/standard/var_unserializer.c" +#line 580 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -610,13 +619,13 @@ yy13: goto yy3; yy14: ++YYCURSOR; -#line 851 "ext/standard/var_unserializer.re" +#line 863 "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 620 "ext/standard/var_unserializer.c" +#line 629 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -646,7 +655,7 @@ yy20: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 706 "ext/standard/var_unserializer.re" +#line 718 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; zend_long elements; @@ -791,7 +800,7 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 795 "ext/standard/var_unserializer.c" +#line 804 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -816,14 +825,14 @@ yy27: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 699 "ext/standard/var_unserializer.re" +#line 711 "ext/standard/var_unserializer.re" { if (!var_hash) return 0; return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 827 "ext/standard/var_unserializer.c" +#line 836 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -844,7 +853,7 @@ yy34: yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 675 "ext/standard/var_unserializer.re" +#line 687 "ext/standard/var_unserializer.re" { zend_long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -868,7 +877,7 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 872 "ext/standard/var_unserializer.c" +#line 881 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -889,7 +898,7 @@ yy41: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 647 "ext/standard/var_unserializer.re" +#line 659 "ext/standard/var_unserializer.re" { size_t len, maxlen; zend_string *str; @@ -917,7 +926,7 @@ yy41: ZVAL_STR(rval, str); return 1; } -#line 921 "ext/standard/var_unserializer.c" +#line 930 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -938,7 +947,7 @@ yy48: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 620 "ext/standard/var_unserializer.re" +#line 632 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -965,7 +974,7 @@ yy48: ZVAL_STRINGL(rval, str, len); return 1; } -#line 969 "ext/standard/var_unserializer.c" +#line 978 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -1053,7 +1062,7 @@ yy61: } yy63: ++YYCURSOR; -#line 611 "ext/standard/var_unserializer.re" +#line 623 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 use_double: @@ -1062,7 +1071,7 @@ use_double: ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 1066 "ext/standard/var_unserializer.c" +#line 1075 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -1121,7 +1130,7 @@ yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 595 "ext/standard/var_unserializer.re" +#line 607 "ext/standard/var_unserializer.re" { *p = YYCURSOR; @@ -1137,7 +1146,7 @@ yy73: return 1; } -#line 1141 "ext/standard/var_unserializer.c" +#line 1150 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1164,7 +1173,7 @@ yy79: if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 569 "ext/standard/var_unserializer.re" +#line 581 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1190,7 +1199,7 @@ yy79: ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } -#line 1194 "ext/standard/var_unserializer.c" +#line 1203 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1198,22 +1207,22 @@ yy83: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 563 "ext/standard/var_unserializer.re" +#line 575 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } -#line 1208 "ext/standard/var_unserializer.c" +#line 1217 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 557 "ext/standard/var_unserializer.re" +#line 569 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } -#line 1217 "ext/standard/var_unserializer.c" +#line 1226 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1236,7 +1245,7 @@ yy91: if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 541 "ext/standard/var_unserializer.re" +#line 548 "ext/standard/var_unserializer.re" { zend_long id; @@ -1248,11 +1257,16 @@ yy91: return 0; } + if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { + ZVAL_UNDEF(rval); + return 1; + } + ZVAL_COPY(rval, rval_ref); return 1; } -#line 1256 "ext/standard/var_unserializer.c" +#line 1270 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1275,7 +1289,7 @@ yy97: if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 513 "ext/standard/var_unserializer.re" +#line 522 "ext/standard/var_unserializer.re" { zend_long id; @@ -1288,14 +1302,12 @@ yy97: } zval_ptr_dtor(rval); - if (Z_ISREF_P(rval_ref)) { - if (!Z_ISUNDEF_P(Z_REFVAL_P(rval_ref))) { - ZVAL_COPY(rval, rval_ref); - } else { - ZVAL_UNDEF(rval); - } - } else if (Z_ISUNDEF_P(rval_ref)) { + if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { ZVAL_UNDEF(rval); + return 1; + } + if (Z_ISREF_P(rval_ref)) { + ZVAL_COPY(rval, rval_ref); } else { ZVAL_NEW_REF(rval_ref, rval_ref); ZVAL_COPY(rval, rval_ref); @@ -1303,9 +1315,9 @@ yy97: return 1; } -#line 1307 "ext/standard/var_unserializer.c" +#line 1319 "ext/standard/var_unserializer.c" } -#line 859 "ext/standard/var_unserializer.re" +#line 871 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index d652d3330a..bb4b016f85 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -369,13 +369,22 @@ string_key: } } - zval_dtor(&key); - if (!php_var_unserialize_ex(data, p, max, var_hash, classes)) { + zval_dtor(&key); return 0; } - var_push_dtor(var_hash, data); + if (UNEXPECTED(Z_ISUNDEF_P(data))) { + if (Z_TYPE(key) == IS_LONG) { + zend_hash_index_del(ht, Z_LVAL(key)); + } else { + zend_hash_del_ind(ht, Z_STR(key)); + } + } else { + var_push_dtor(var_hash, data); + } + + zval_dtor(&key); if (elements && *(*p-1) != ';' && *(*p-1) != '}') { (*p)--; @@ -522,14 +531,12 @@ PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) } zval_ptr_dtor(rval); - if (Z_ISREF_P(rval_ref)) { - if (!Z_ISUNDEF_P(Z_REFVAL_P(rval_ref))) { - ZVAL_COPY(rval, rval_ref); - } else { - ZVAL_UNDEF(rval); - } - } else if (Z_ISUNDEF_P(rval_ref)) { + if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { ZVAL_UNDEF(rval); + return 1; + } + if (Z_ISREF_P(rval_ref)) { + ZVAL_COPY(rval, rval_ref); } else { ZVAL_NEW_REF(rval_ref, rval_ref); ZVAL_COPY(rval, rval_ref); @@ -549,6 +556,11 @@ PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) return 0; } + if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) { + ZVAL_UNDEF(rval); + return 1; + } + ZVAL_COPY(rval, rval_ref); return 1; |