From 0af75d6b1ae3230fdb8c58b4a2df73a236840e9f Mon Sep 17 00:00:00 2001 From: Stanislav Malyshev Date: Fri, 23 Mar 2007 20:15:22 +0000 Subject: [PATCH] fix MOPB-29 - unserialize modifier S does not calculate length correctly # reported by Stefan Esser --- .../tests/serialize/unserializeS.phpt | 14 + ext/standard/var_unserializer.c | 1257 +++++++++++------ ext/standard/var_unserializer.re | 17 +- 3 files changed, 814 insertions(+), 474 deletions(-) create mode 100755 ext/standard/tests/serialize/unserializeS.phpt diff --git a/ext/standard/tests/serialize/unserializeS.phpt b/ext/standard/tests/serialize/unserializeS.phpt new file mode 100755 index 0000000000..8516f7183e --- /dev/null +++ b/ext/standard/tests/serialize/unserializeS.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug MOPB-29 (wrong length calculation for S) +--INI-- +error_reporting=0 +--FILE-- +1,str_repeat('"', 200)."2"=>1); + +$data = unserialize($str); +var_dump($data); + +--EXPECT-- +string(100) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index f1684fd781..4f140c1ed4 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -1,10 +1,10 @@ -/* Generated by re2c 0.9.12 on Thu Dec 14 15:59:31 2006 */ +/* Generated by re2c 0.11.2 on Fri Mar 23 13:13:16 2007 */ #line 1 "ext/standard/var_unserializer.re" /* +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | + | Copyright (c) 1997-2006 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -140,12 +140,18 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) /* }}} */ -static char *unserialize_str(const unsigned char **p, int len) +static char *unserialize_str(const unsigned char **p, size_t *len) { - int i, j; - char *str = emalloc(len+1); + size_t i, j; + char *str = safe_emalloc(*len, 1, 1); + unsigned char *end = *p+*len; - for (i = 0; i < len; i++) { + if(end < *p) { + efree(str); + return NULL; + } + + for (i = 0; i < *len && *p < end; i++) { if (**p != '\\') { str[i] = (char)**p; } else { @@ -169,6 +175,7 @@ static char *unserialize_str(const unsigned char **p, int len) (*p)++; } str[i] = 0; + *len = i; return str; } @@ -179,7 +186,7 @@ static char *unserialize_str(const unsigned char **p, int len) #define YYMARKER marker -#line 187 "ext/standard/var_unserializer.re" +#line 194 "ext/standard/var_unserializer.re" @@ -386,53 +393,16 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) -{ - static unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - }; - -#line 426 "ext/standard/var_unserializer.c" + +#line 398 "" { YYCTYPE yych; - unsigned int yyaccept = 0; - goto yy0; - ++YYCURSOR; -yy0: + if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; - switch(yych){ - case 'C': case 'O': goto yy13; + switch(yych) { + case 'C': + case 'O': goto yy13; case 'N': goto yy5; case 'R': goto yy2; case 'S': goto yy10; @@ -446,97 +416,150 @@ yy0: case '}': goto yy14; default: goto yy16; } -yy2: yyaccept = 0; +yy2: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy95; - goto yy3; + switch(yych) { + case ':': goto yy95; + default: goto yy3; + } yy3: -#line 687 "ext/standard/var_unserializer.re" -{ return 0; } -#line 457 "ext/standard/var_unserializer.c" -yy4: yyaccept = 0; +#line 694 "ext/standard/var_unserializer.re" + { return 0; } +#line 429 "" +yy4: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy89; - goto yy3; -yy5: yych = *++YYCURSOR; - if(yych == ';') goto yy87; - goto yy3; -yy6: yyaccept = 0; + switch(yych) { + case ':': goto yy89; + default: goto yy3; + } +yy5: + yych = *++YYCURSOR; + switch(yych) { + case ';': goto yy87; + default: goto yy3; + } +yy6: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy83; - goto yy3; -yy7: yyaccept = 0; + switch(yych) { + case ':': goto yy83; + default: goto yy3; + } +yy7: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy77; - goto yy3; -yy8: yyaccept = 0; + switch(yych) { + case ':': goto yy77; + default: goto yy3; + } +yy8: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy53; - goto yy3; -yy9: yyaccept = 0; + switch(yych) { + case ':': goto yy53; + default: goto yy3; + } +yy9: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy46; - goto yy3; -yy10: yyaccept = 0; + switch(yych) { + case ':': goto yy46; + default: goto yy3; + } +yy10: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy39; - goto yy3; -yy11: yyaccept = 0; + switch(yych) { + case ':': goto yy39; + default: goto yy3; + } +yy11: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy32; - goto yy3; -yy12: yyaccept = 0; + switch(yych) { + case ':': goto yy32; + default: goto yy3; + } +yy12: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy25; - goto yy3; -yy13: yyaccept = 0; + switch(yych) { + case ':': goto yy25; + default: goto yy3; + } +yy13: yych = *(YYMARKER = ++YYCURSOR); - if(yych == ':') goto yy17; - goto yy3; -yy14: ++YYCURSOR; - goto yy15; -yy15: -#line 681 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case ':': goto yy17; + default: goto yy3; + } +yy14: + ++YYCURSOR; +#line 688 "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 506 "ext/standard/var_unserializer.c" -yy16: yych = *++YYCURSOR; +#line 498 "" +yy16: + yych = *++YYCURSOR; goto yy3; -yy17: yych = *++YYCURSOR; - if(yybm[0+yych] & 128) { - goto yy20; - } - if(yych == '+') goto yy19; - goto yy18; -yy18: YYCURSOR = YYMARKER; - switch(yyaccept){ - case 0: goto yy3; - } -yy19: yych = *++YYCURSOR; - if(yybm[0+yych] & 128) { - goto yy20; - } - goto yy18; -yy20: ++YYCURSOR; +yy17: + yych = *++YYCURSOR; + switch(yych) { + case '+': goto yy19; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy20; + default: goto yy18; + } +yy18: + YYCURSOR = YYMARKER; + goto yy3; +yy19: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy20; + default: goto yy18; + } +yy20: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - goto yy21; -yy21: if(yybm[0+yych] & 128) { - goto yy20; - } - if(yych != ':') goto yy18; - goto yy22; -yy22: yych = *++YYCURSOR; - if(yych != '"') goto yy18; - goto yy23; -yy23: ++YYCURSOR; - goto yy24; -yy24: -#line 569 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy20; + case ':': goto yy22; + default: goto yy18; + } +yy22: + yych = *++YYCURSOR; + switch(yych) { + case '"': goto yy23; + default: goto yy18; + } +yy23: + ++YYCURSOR; +#line 576 "ext/standard/var_unserializer.re" + { size_t len, len2, len3, maxlen; long elements; char *class_name; @@ -647,69 +670,133 @@ yy24: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 651 "ext/standard/var_unserializer.c" -yy25: yych = *++YYCURSOR; - if(yych <= ','){ - if(yych != '+') goto yy18; - goto yy26; - } else { - if(yych <= '-') goto yy26; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy27; - goto yy18; - } -yy26: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy27; -yy27: ++YYCURSOR; +#line 674 "" +yy25: + yych = *++YYCURSOR; + switch(yych) { + case '+': + case '-': goto yy26; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy27; + default: goto yy18; + } +yy26: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy27; + default: goto yy18; + } +yy27: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - goto yy28; -yy28: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy27; - if(yych >= ';') goto yy18; - goto yy29; -yy29: yych = *++YYCURSOR; - if(yych != '"') goto yy18; - goto yy30; -yy30: ++YYCURSOR; - goto yy31; -yy31: -#line 561 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy27; + case ':': goto yy29; + default: goto yy18; + } +yy29: + yych = *++YYCURSOR; + switch(yych) { + case '"': goto yy30; + default: goto yy18; + } +yy30: + ++YYCURSOR; +#line 568 "ext/standard/var_unserializer.re" + { INIT_PZVAL(*rval); return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 688 "ext/standard/var_unserializer.c" -yy32: yych = *++YYCURSOR; - if(yych == '+') goto yy33; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy34; - goto yy18; -yy33: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy34; -yy34: ++YYCURSOR; +#line 741 "" +yy32: + yych = *++YYCURSOR; + switch(yych) { + case '+': goto yy33; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy34; + default: goto yy18; + } +yy33: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy34; + default: goto yy18; + } +yy34: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - goto yy35; -yy35: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy34; - if(yych >= ';') goto yy18; - goto yy36; -yy36: yych = *++YYCURSOR; - if(yych != '{') goto yy18; - goto yy37; -yy37: ++YYCURSOR; - goto yy38; -yy38: -#line 539 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy34; + case ':': goto yy36; + default: goto yy18; + } +yy36: + yych = *++YYCURSOR; + switch(yych) { + case '{': goto yy37; + default: goto yy18; + } +yy37: + ++YYCURSOR; +#line 546 "ext/standard/var_unserializer.re" + { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ *p = YYCURSOR; @@ -730,32 +817,66 @@ yy38: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 734 "ext/standard/var_unserializer.c" -yy39: yych = *++YYCURSOR; - if(yych == '+') goto yy40; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy41; - goto yy18; -yy40: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy41; -yy41: ++YYCURSOR; +#line 821 "" +yy39: + yych = *++YYCURSOR; + switch(yych) { + case '+': goto yy40; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy41; + default: goto yy18; + } +yy40: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy41; + default: goto yy18; + } +yy41: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - goto yy42; -yy42: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy41; - if(yych >= ';') goto yy18; - goto yy43; -yy43: yych = *++YYCURSOR; - if(yych != '"') goto yy18; - goto yy44; -yy44: ++YYCURSOR; - goto yy45; -yy45: -#line 510 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy41; + case ':': goto yy43; + default: goto yy18; + } +yy43: + yych = *++YYCURSOR; + switch(yych) { + case '"': goto yy44; + default: goto yy18; + } +yy44: + ++YYCURSOR; +#line 517 "ext/standard/var_unserializer.re" + { size_t len, maxlen; char *str; @@ -766,7 +887,7 @@ yy45: return 0; } - if ((str = unserialize_str(&YYCURSOR, len)) == NULL) { + if ((str = unserialize_str(&YYCURSOR, &len)) == NULL) { return 0; } @@ -783,32 +904,66 @@ yy45: ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 787 "ext/standard/var_unserializer.c" -yy46: yych = *++YYCURSOR; - if(yych == '+') goto yy47; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy48; - goto yy18; -yy47: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy48; -yy48: ++YYCURSOR; +#line 908 "" +yy46: + yych = *++YYCURSOR; + switch(yych) { + case '+': goto yy47; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy48; + default: goto yy18; + } +yy47: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy48; + default: goto yy18; + } +yy48: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); yych = *YYCURSOR; - goto yy49; -yy49: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy48; - if(yych >= ';') goto yy18; - goto yy50; -yy50: yych = *++YYCURSOR; - if(yych != '"') goto yy18; - goto yy51; -yy51: ++YYCURSOR; - goto yy52; -yy52: -#line 482 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy48; + case ':': goto yy50; + default: goto yy18; + } +yy50: + yych = *++YYCURSOR; + switch(yych) { + case '"': goto yy51; + default: goto yy18; + } +yy51: + ++YYCURSOR; +#line 489 "ext/standard/var_unserializer.re" + { size_t len, maxlen; char *str; @@ -835,164 +990,241 @@ yy52: ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 839 "ext/standard/var_unserializer.c" -yy53: yych = *++YYCURSOR; - if(yych <= '/'){ - if(yych <= ','){ - if(yych == '+') goto yy57; - goto yy18; - } else { - if(yych <= '-') goto yy55; - if(yych <= '.') goto yy60; - goto yy18; - } - } else { - if(yych <= 'I'){ - if(yych <= '9') goto yy58; - if(yych <= 'H') goto yy18; - goto yy56; - } else { - if(yych != 'N') goto yy18; - goto yy54; - } +#line 994 "" +yy53: + yych = *++YYCURSOR; + switch(yych) { + case '+': goto yy57; + case '-': goto yy55; + case '.': goto yy60; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case 'I': goto yy56; + case 'N': goto yy54; + default: goto yy18; + } +yy54: + yych = *++YYCURSOR; + switch(yych) { + case 'A': goto yy76; + default: goto yy18; + } +yy55: + yych = *++YYCURSOR; + switch(yych) { + case '.': goto yy60; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case 'I': goto yy56; + default: goto yy18; + } +yy56: + yych = *++YYCURSOR; + switch(yych) { + case 'N': goto yy72; + default: goto yy18; + } +yy57: + yych = *++YYCURSOR; + switch(yych) { + case '.': goto yy60; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + default: goto yy18; } -yy54: yych = *++YYCURSOR; - if(yych == 'A') goto yy76; - goto yy18; -yy55: yych = *++YYCURSOR; - if(yych <= '/'){ - if(yych == '.') goto yy60; - goto yy18; - } else { - if(yych <= '9') goto yy58; - if(yych != 'I') goto yy18; - goto yy56; - } -yy56: yych = *++YYCURSOR; - if(yych == 'N') goto yy72; - goto yy18; -yy57: yych = *++YYCURSOR; - if(yych == '.') goto yy60; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy58; -yy58: ++YYCURSOR; +yy58: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - goto yy59; -yy59: if(yych <= ':'){ - if(yych <= '.'){ - if(yych <= '-') goto yy18; - goto yy70; - } else { - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy58; - goto yy18; - } - } else { - if(yych <= 'E'){ - if(yych <= ';') goto yy63; - if(yych <= 'D') goto yy18; - goto yy65; - } else { - if(yych == 'e') goto yy65; - goto yy18; - } + switch(yych) { + case '.': goto yy70; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy58; + case ';': goto yy63; + case 'E': + case 'e': goto yy65; + default: goto yy18; } -yy60: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy61; -yy61: ++YYCURSOR; +yy60: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy61; + default: goto yy18; + } +yy61: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - goto yy62; -yy62: if(yych <= ';'){ - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy61; - if(yych <= ':') goto yy18; - goto yy63; - } else { - if(yych <= 'E'){ - if(yych <= 'D') goto yy18; - goto yy65; - } else { - if(yych == 'e') goto yy65; - goto yy18; - } + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy61; + case ';': goto yy63; + case 'E': + case 'e': goto yy65; + default: goto yy18; } -yy63: ++YYCURSOR; - goto yy64; -yy64: -#line 475 "ext/standard/var_unserializer.re" -{ +yy63: + ++YYCURSOR; +#line 482 "ext/standard/var_unserializer.re" + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 935 "ext/standard/var_unserializer.c" -yy65: yych = *++YYCURSOR; - if(yych <= ','){ - if(yych != '+') goto yy18; - goto yy66; - } else { - if(yych <= '-') goto yy66; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy67; - goto yy18; - } -yy66: yych = *++YYCURSOR; - if(yych <= ','){ - if(yych == '+') goto yy69; - goto yy18; - } else { - if(yych <= '-') goto yy69; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy67; - } -yy67: ++YYCURSOR; +#line 1125 "" +yy65: + yych = *++YYCURSOR; + switch(yych) { + case '+': + case '-': goto yy66; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy18; + } +yy66: + yych = *++YYCURSOR; + switch(yych) { + case '+': + case '-': goto yy69; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy18; + } +yy67: + ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy68; -yy68: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy67; - if(yych == ';') goto yy63; - goto yy18; -yy69: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy67; - goto yy18; -yy70: ++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + case ';': goto yy63; + default: goto yy18; + } +yy69: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy67; + default: goto yy18; + } +yy70: + ++YYCURSOR; if((YYLIMIT - YYCURSOR) < 4) YYFILL(4); yych = *YYCURSOR; - goto yy71; -yy71: if(yych <= ';'){ - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy70; - if(yych <= ':') goto yy18; - goto yy63; - } else { - if(yych <= 'E'){ - if(yych <= 'D') goto yy18; - goto yy65; - } else { - if(yych == 'e') goto yy65; - goto yy18; - } + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy70; + case ';': goto yy63; + case 'E': + case 'e': goto yy65; + default: goto yy18; } -yy72: yych = *++YYCURSOR; - if(yych != 'F') goto yy18; - goto yy73; -yy73: yych = *++YYCURSOR; - if(yych != ';') goto yy18; - goto yy74; -yy74: ++YYCURSOR; - goto yy75; -yy75: -#line 460 "ext/standard/var_unserializer.re" -{ +yy72: + yych = *++YYCURSOR; + switch(yych) { + case 'F': goto yy73; + default: goto yy18; + } +yy73: + yych = *++YYCURSOR; + switch(yych) { + case ';': goto yy74; + default: goto yy18; + } +yy74: + ++YYCURSOR; +#line 467 "ext/standard/var_unserializer.re" + { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -1006,99 +1238,160 @@ yy75: return 1; } -#line 1010 "ext/standard/var_unserializer.c" -yy76: yych = *++YYCURSOR; - if(yych == 'N') goto yy73; - goto yy18; -yy77: yych = *++YYCURSOR; - if(yych <= ','){ - if(yych != '+') goto yy18; - goto yy78; - } else { - if(yych <= '-') goto yy78; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy79; - goto yy18; - } -yy78: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy79; -yy79: ++YYCURSOR; +#line 1242 "" +yy76: + yych = *++YYCURSOR; + switch(yych) { + case 'N': goto yy73; + default: goto yy18; + } +yy77: + yych = *++YYCURSOR; + switch(yych) { + case '+': + case '-': goto yy78; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy79; + default: goto yy18; + } +yy78: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy79; + default: goto yy18; + } +yy79: + ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy80; -yy80: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy79; - if(yych != ';') goto yy18; - goto yy81; -yy81: ++YYCURSOR; - goto yy82; -yy82: -#line 453 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy79; + case ';': goto yy81; + default: goto yy18; + } +yy81: + ++YYCURSOR; +#line 460 "ext/standard/var_unserializer.re" + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1046 "ext/standard/var_unserializer.c" -yy83: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= '2') goto yy18; - goto yy84; -yy84: yych = *++YYCURSOR; - if(yych != ';') goto yy18; - goto yy85; -yy85: ++YYCURSOR; - goto yy86; -yy86: -#line 446 "ext/standard/var_unserializer.re" -{ +#line 1308 "" +yy83: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': goto yy84; + default: goto yy18; + } +yy84: + yych = *++YYCURSOR; + switch(yych) { + case ';': goto yy85; + default: goto yy18; + } +yy85: + ++YYCURSOR; +#line 453 "ext/standard/var_unserializer.re" + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1064 "ext/standard/var_unserializer.c" -yy87: ++YYCURSOR; - goto yy88; -yy88: -#line 439 "ext/standard/var_unserializer.re" -{ +#line 1331 "" +yy87: + ++YYCURSOR; +#line 446 "ext/standard/var_unserializer.re" + { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1075 "ext/standard/var_unserializer.c" -yy89: yych = *++YYCURSOR; - if(yych <= ','){ - if(yych != '+') goto yy18; - goto yy90; - } else { - if(yych <= '-') goto yy90; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy91; - goto yy18; - } -yy90: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy91; -yy91: ++YYCURSOR; +#line 1341 "" +yy89: + yych = *++YYCURSOR; + switch(yych) { + case '+': + case '-': goto yy90; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + default: goto yy18; + } +yy90: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + default: goto yy18; + } +yy91: + ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy92; -yy92: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy91; - if(yych != ';') goto yy18; - goto yy93; -yy93: ++YYCURSOR; - goto yy94; -yy94: -#line 416 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy91; + case ';': goto yy93; + default: goto yy18; + } +yy93: + ++YYCURSOR; +#line 423 "ext/standard/var_unserializer.re" + { long id; *p = YYCURSOR; @@ -1120,34 +1413,61 @@ yy94: return 1; } -#line 1124 "ext/standard/var_unserializer.c" -yy95: yych = *++YYCURSOR; - if(yych <= ','){ - if(yych != '+') goto yy18; - goto yy96; - } else { - if(yych <= '-') goto yy96; - if(yych <= '/') goto yy18; - if(yych <= '9') goto yy97; - goto yy18; - } -yy96: yych = *++YYCURSOR; - if(yych <= '/') goto yy18; - if(yych >= ':') goto yy18; - goto yy97; -yy97: ++YYCURSOR; +#line 1417 "" +yy95: + yych = *++YYCURSOR; + switch(yych) { + case '+': + case '-': goto yy96; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy97; + default: goto yy18; + } +yy96: + yych = *++YYCURSOR; + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy97; + default: goto yy18; + } +yy97: + ++YYCURSOR; if(YYLIMIT == YYCURSOR) YYFILL(1); yych = *YYCURSOR; - goto yy98; -yy98: if(yych <= '/') goto yy18; - if(yych <= '9') goto yy97; - if(yych != ';') goto yy18; - goto yy99; -yy99: ++YYCURSOR; - goto yy100; -yy100: -#line 395 "ext/standard/var_unserializer.re" -{ + switch(yych) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy97; + case ';': goto yy99; + default: goto yy18; + } +yy99: + ++YYCURSOR; +#line 402 "ext/standard/var_unserializer.re" + { long id; *p = YYCURSOR; @@ -1167,10 +1487,9 @@ yy100: return 1; } -#line 1171 "ext/standard/var_unserializer.c" -} +#line 1491 "" } -#line 689 "ext/standard/var_unserializer.re" +#line 696 "ext/standard/var_unserializer.re" return 0; diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 1fbcbdf92a..072f6e86a0 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -138,12 +138,18 @@ PHPAPI void var_destroy(php_unserialize_data_t *var_hashx) /* }}} */ -static char *unserialize_str(const unsigned char **p, int len) +static char *unserialize_str(const unsigned char **p, size_t *len) { - int i, j; - char *str = emalloc(len+1); + size_t i, j; + char *str = safe_emalloc(*len, 1, 1); + unsigned char *end = *p+*len; - for (i = 0; i < len; i++) { + if(end < *p) { + efree(str); + return NULL; + } + + for (i = 0; i < *len && *p < end; i++) { if (**p != '\\') { str[i] = (char)**p; } else { @@ -167,6 +173,7 @@ static char *unserialize_str(const unsigned char **p, int len) (*p)++; } str[i] = 0; + *len = i; return str; } @@ -518,7 +525,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) return 0; } - if ((str = unserialize_str(&YYCURSOR, len)) == NULL) { + if ((str = unserialize_str(&YYCURSOR, &len)) == NULL) { return 0; } -- 2.40.0