cvs: php-src /ext/standard var_unserializer.c var_unserializer.re /ext/standard/tests/serialize unserializeS.phpt

From: Date: Fri, 23 Mar 2007 20:34:11 +0000
Subject: cvs: php-src /ext/standard var_unserializer.c var_unserializer.re /ext/standard/tests/serialize unserializeS.phpt
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-43623@lists.php.net to get a copy of this message
stas Fri Mar 23 20:34:11 2007 UTC Modified files: /php-src/ext/standard var_unserializer.c var_unserializer.re /php-src/ext/standard/tests/serialize unserializeS.phpt Log: MFB: fix MOPB-29 - unserialize modifier S does not calculate length correctly

http://cvs.php.net/viewvc.cgi/php-src/ext/standard/var_unserializer.c?r1=1.84&r2=1.85&diff_format=u Index: php-src/ext/standard/var_unserializer.c diff -u php-src/ext/standard/var_unserializer.c:1.84 php-src/ext/standard/var_unserializer.c:1.85 --- php-src/ext/standard/var_unserializer.c:1.84 Mon Jan 1 09:29:32 2007 +++ php-src/ext/standard/var_unserializer.c Fri Mar 23 20:34:11 2007 @@ -1,10 +1,10 @@ -/* Generated by re2c 0.10.2 on Thu Dec 21 19:19:25 2007 */ +/* Generated by re2c 0.11.2 on Fri Mar 23 13:33:19 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 | @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.c,v 1.84 2007/01/01 09:29:32 sebastian Exp $ */ +/* $Id: var_unserializer.c,v 1.85 2007/03/23 20:34:11 stas Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -112,12 +112,18 @@ return ustr; } -static char *unserialize_str(const unsigned char **p, int len) +static char *unserialize_str(const unsigned char **p, int *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 { @@ -141,6 +147,7 @@ (*p)++; } str[i] = 0; + *len = i; return str; } @@ -211,7 +218,7 @@ #define YYMARKER marker -#line 219 "ext/standard/var_unserializer.re" +#line 226 "ext/standard/var_unserializer.re" @@ -439,7 +446,7 @@ { - static unsigned char yybm[] = { + static const 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, @@ -474,13 +481,13 @@ 0, 0, 0, 0, 0, 0, 0, 0, }; -#line 478 "ext/standard/var_unserializer.c" +#line 485 "ext/standard/var_unserializer.c" { YYCTYPE yych; if((YYLIMIT - YYCURSOR) < 7) YYFILL(7); yych = *YYCURSOR; - switch(yych){ + switch(yych) { case 'C': case 'O': goto yy14; case 'N': goto yy5; @@ -501,9 +508,9 @@ yych = *(YYMARKER = ++YYCURSOR); if(yych == ':') goto yy103; yy3: -#line 769 "ext/standard/var_unserializer.re" +#line 776 "ext/standard/var_unserializer.re" { return 0; } -#line 507 "ext/standard/var_unserializer.c" +#line 514 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if(yych == ':') goto yy97; @@ -550,13 +557,13 @@ goto yy3; yy15: ++YYCURSOR; -#line 763 "ext/standard/var_unserializer.re" +#line 770 "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 560 "ext/standard/var_unserializer.c" +#line 567 "ext/standard/var_unserializer.c" yy17: yych = *++YYCURSOR; goto yy3; @@ -586,7 +593,7 @@ yych = *++YYCURSOR; if(yych != '"') goto yy19; ++YYCURSOR; -#line 650 "ext/standard/var_unserializer.re" +#line 657 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; long elements; @@ -699,7 +706,7 @@ return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 703 "ext/standard/var_unserializer.c" +#line 710 "ext/standard/var_unserializer.c" yy26: yych = *++YYCURSOR; if(yych <= ',') { @@ -724,7 +731,7 @@ yych = *++YYCURSOR; if(yych != '"') goto yy19; ++YYCURSOR; -#line 642 "ext/standard/var_unserializer.re" +#line 649 "ext/standard/var_unserializer.re" { INIT_PZVAL(*rval); @@ -732,7 +739,7 @@ return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 736 "ext/standard/var_unserializer.c" +#line 743 "ext/standard/var_unserializer.c" yy33: yych = *++YYCURSOR; if(yych == '+') goto yy34; @@ -753,7 +760,7 @@ yych = *++YYCURSOR; if(yych != '{') goto yy19; ++YYCURSOR; -#line 620 "ext/standard/var_unserializer.re" +#line 627 "ext/standard/var_unserializer.re" { long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -775,7 +782,7 @@ return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 779 "ext/standard/var_unserializer.c" +#line 786 "ext/standard/var_unserializer.c" yy40: yych = *++YYCURSOR; if(yych == '+') goto yy41; @@ -796,7 +803,7 @@ yych = *++YYCURSOR; if(yych != '"') goto yy19; ++YYCURSOR; -#line 591 "ext/standard/var_unserializer.re" +#line 598 "ext/standard/var_unserializer.re" { size_t len, maxlen; UChar *ustr; @@ -825,7 +832,7 @@ ZVAL_UNICODEL(*rval, ustr, len, 0); return 1; } -#line 829 "ext/standard/var_unserializer.c" +#line 836 "ext/standard/var_unserializer.c" yy47: yych = *++YYCURSOR; if(yych == '+') goto yy48; @@ -846,7 +853,7 @@ yych = *++YYCURSOR; if(yych != '"') goto yy19; ++YYCURSOR; -#line 562 "ext/standard/var_unserializer.re" +#line 569 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -858,7 +865,7 @@ return 0; } - if ((str = unserialize_str(&YYCURSOR, len)) == NULL) { + if ((str = unserialize_str(&YYCURSOR, &len)) == NULL) { return 0; } @@ -875,7 +882,7 @@ ZVAL_STRINGL(*rval, str, len, 0); return 1; } -#line 879 "ext/standard/var_unserializer.c" +#line 886 "ext/standard/var_unserializer.c" yy54: yych = *++YYCURSOR; if(yych == '+') goto yy55; @@ -896,7 +903,7 @@ yych = *++YYCURSOR; if(yych != '"') goto yy19; ++YYCURSOR; -#line 534 "ext/standard/var_unserializer.re" +#line 541 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -924,7 +931,7 @@ ZVAL_STRINGL(*rval, str, len, 1); return 1; } -#line 928 "ext/standard/var_unserializer.c" +#line 935 "ext/standard/var_unserializer.c" yy61: yych = *++YYCURSOR; if(yych <= '/') { @@ -1012,14 +1019,14 @@ } yy71: ++YYCURSOR; -#line 527 "ext/standard/var_unserializer.re" +#line 534 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 1023 "ext/standard/var_unserializer.c" +#line 1030 "ext/standard/var_unserializer.c" yy73: yych = *++YYCURSOR; if(yych <= ',') { @@ -1078,7 +1085,7 @@ yych = *++YYCURSOR; if(yych != ';') goto yy19; ++YYCURSOR; -#line 512 "ext/standard/var_unserializer.re" +#line 519 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); @@ -1093,7 +1100,7 @@ return 1; } -#line 1097 "ext/standard/var_unserializer.c" +#line 1104 "ext/standard/var_unserializer.c" yy84: yych = *++YYCURSOR; if(yych == 'N') goto yy81; @@ -1120,14 +1127,14 @@ if(yych <= '9') goto yy87; if(yych != ';') goto yy19; ++YYCURSOR; -#line 505 "ext/standard/var_unserializer.re" +#line 512 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); return 1; } -#line 1131 "ext/standard/var_unserializer.c" +#line 1138 "ext/standard/var_unserializer.c" yy91: yych = *++YYCURSOR; if(yych <= '/') goto yy19; @@ -1135,24 +1142,24 @@ yych = *++YYCURSOR; if(yych != ';') goto yy19; ++YYCURSOR; -#line 498 "ext/standard/var_unserializer.re" +#line 505 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); return 1; } -#line 1146 "ext/standard/var_unserializer.c" +#line 1153 "ext/standard/var_unserializer.c" yy95: ++YYCURSOR; -#line 491 "ext/standard/var_unserializer.re" +#line 498 "ext/standard/var_unserializer.re" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); return 1; } -#line 1156 "ext/standard/var_unserializer.c" +#line 1163 "ext/standard/var_unserializer.c" yy97: yych = *++YYCURSOR; if(yych <= ',') { @@ -1175,7 +1182,7 @@ if(yych <= '9') goto yy99; if(yych != ';') goto yy19; ++YYCURSOR; -#line 468 "ext/standard/var_unserializer.re" +#line 475 "ext/standard/var_unserializer.re" { long id; @@ -1198,7 +1205,7 @@ return 1; } -#line 1202 "ext/standard/var_unserializer.c" +#line 1209 "ext/standard/var_unserializer.c" yy103: yych = *++YYCURSOR; if(yych <= ',') { @@ -1221,7 +1228,7 @@ if(yych <= '9') goto yy105; if(yych != ';') goto yy19; ++YYCURSOR; -#line 447 "ext/standard/var_unserializer.re" +#line 454 "ext/standard/var_unserializer.re" { long id; @@ -1242,10 +1249,10 @@ return 1; } -#line 1246 "ext/standard/var_unserializer.c" +#line 1253 "ext/standard/var_unserializer.c" } } -#line 771 "ext/standard/var_unserializer.re" +#line 778 "ext/standard/var_unserializer.re" return 0; http://cvs.php.net/viewvc.cgi/php-src/ext/standard/var_unserializer.re?r1=1.62&r2=1.63&diff_format=u Index: php-src/ext/standard/var_unserializer.re diff -u php-src/ext/standard/var_unserializer.re:1.62 php-src/ext/standard/var_unserializer.re:1.63 --- php-src/ext/standard/var_unserializer.re:1.62 Fri Dec 22 00:47:27 2006 +++ php-src/ext/standard/var_unserializer.re Fri Mar 23 20:34:11 2007 @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.re,v 1.62 2006/12/22 00:47:27 helly Exp $ */ +/* $Id: var_unserializer.re,v 1.63 2007/03/23 20:34:11 stas Exp $ */ #include "php.h" #include "ext/standard/php_var.h" @@ -110,12 +110,18 @@ return ustr; } -static char *unserialize_str(const unsigned char **p, int len) +static char *unserialize_str(const unsigned char **p, int *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 { @@ -139,6 +145,7 @@ (*p)++; } str[i] = 0; + *len = i; return str; } @@ -570,7 +577,7 @@ return 0; } - if ((str = unserialize_str(&YYCURSOR, len)) == NULL) { + if ((str = unserialize_str(&YYCURSOR, &len)) == NULL) { return 0; } http://cvs.php.net/viewvc.cgi/php-src/ext/standard/tests/serialize/unserializeS.phpt?r1=1.1&r2=1.2&diff_format=u Index: php-src/ext/standard/tests/serialize/unserializeS.phpt diff -u /dev/null php-src/ext/standard/tests/serialize/unserializeS.phpt:1.2 --- /dev/null Fri Mar 23 20:34:11 2007 +++ php-src/ext/standard/tests/serialize/unserializeS.phpt Fri Mar 23 20:34:11 2007 @@ -0,0 +1,14 @@ +--TEST-- +Bug MOPB-29 (wrong length calculation for S) +--INI-- +error_reporting=0 +--FILE-- +<?php +$str = 'S:'.(100*3).':"'.str_repeat('\61', 100).'"'; +$arr = array(str_repeat('"', 200)."1"=>1,str_repeat('"', 200)."2"=>1); + +$data = unserialize($str); +var_dump($data); + +--EXPECT-- +string(100) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
« previous php.cvs (#43623) next »