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"
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php