]> granicus.if.org Git - php/commitdiff
Fixed bug #71840 (Unserialize accepts wrongly data)
authorXinchen Hui <laruence@gmail.com>
Thu, 17 Mar 2016 06:27:27 +0000 (14:27 +0800)
committerXinchen Hui <laruence@gmail.com>
Thu, 17 Mar 2016 07:15:28 +0000 (15:15 +0800)
NEWS
ext/standard/tests/serialize/bug71840.phpt [new file with mode: 0644]
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

diff --git a/NEWS b/NEWS
index 40b8c7d8ec8bf026d59e558da693b739cf5ad334..c839954848d2448331a64dc3fead08e2336d4fce 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,9 @@ PHP                                                                        NEWS
 |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 ?? ??? 2016, PHP 5.6.21
 
+- Standard:
+  . Fixed bug #71840 (Unserialize accepts wrongly data). (Ryat, Laruence)
+
 31 Marc 2016, PHP 5.6.20
 
 - CLI Server:
diff --git a/ext/standard/tests/serialize/bug71840.phpt b/ext/standard/tests/serialize/bug71840.phpt
new file mode 100644 (file)
index 0000000..6cbf04b
--- /dev/null
@@ -0,0 +1,9 @@
+--TEST--
+Bug #71840 (Unserialize accepts wrongly data)
+--FILE--
+<?php
+var_dump(unserialize('a:1:{s:0:""0a:0:{}}'));
+?>
+--EXPECTF--
+Notice: unserialize(): Error at offset 11 of 19 bytes in %sbug71840.php on line %d
+bool(false)
index 90db7f4a5f9cb508724d9d1501efbd4da061a8b4..1e45b03fcc644f7703f3f1cb9089b9cb37abf048 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.7.5 */
+/* Generated by re2c 0.13.5 */
 #line 1 "ext/standard/var_unserializer.re"
 /*
   +----------------------------------------------------------------------+
@@ -542,7 +542,7 @@ yy2:
        yych = *(YYMARKER = ++YYCURSOR);
        if (yych == ':') goto yy95;
 yy3:
-#line 840 "ext/standard/var_unserializer.re"
+#line 851 "ext/standard/var_unserializer.re"
        { return 0; }
 #line 548 "ext/standard/var_unserializer.c"
 yy4:
@@ -587,7 +587,7 @@ yy13:
        goto yy3;
 yy14:
        ++YYCURSOR;
-#line 834 "ext/standard/var_unserializer.re"
+#line 845 "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");
@@ -619,12 +619,11 @@ yy20:
        if (yybm[0+yych] & 128) {
                goto yy20;
        }
-       if (yych <= '/') goto yy18;
-       if (yych >= ';') goto yy18;
+       if (yych != ':') goto yy18;
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 687 "ext/standard/var_unserializer.re"
+#line 698 "ext/standard/var_unserializer.re"
        {
        size_t len, len2, len3, maxlen;
        long elements;
@@ -771,7 +770,7 @@ yy20:
 
        return object_common2(UNSERIALIZE_PASSTHRU, elements);
 }
-#line 775 "ext/standard/var_unserializer.c"
+#line 774 "ext/standard/var_unserializer.c"
 yy25:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -796,7 +795,7 @@ yy27:
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 678 "ext/standard/var_unserializer.re"
+#line 689 "ext/standard/var_unserializer.re"
        {
     if (!var_hash) return 0;
 
@@ -805,7 +804,7 @@ yy27:
        return object_common2(UNSERIALIZE_PASSTHRU,
                        object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
 }
-#line 809 "ext/standard/var_unserializer.c"
+#line 808 "ext/standard/var_unserializer.c"
 yy32:
        yych = *++YYCURSOR;
        if (yych == '+') goto yy33;
@@ -826,7 +825,7 @@ yy34:
        yych = *++YYCURSOR;
        if (yych != '{') goto yy18;
        ++YYCURSOR;
-#line 657 "ext/standard/var_unserializer.re"
+#line 668 "ext/standard/var_unserializer.re"
        {
        long elements = parse_iv(start + 2);
        /* use iv() not uiv() in order to check data range */
@@ -847,7 +846,7 @@ yy34:
 
        return finish_nested_data(UNSERIALIZE_PASSTHRU);
 }
-#line 851 "ext/standard/var_unserializer.c"
+#line 850 "ext/standard/var_unserializer.c"
 yy39:
        yych = *++YYCURSOR;
        if (yych == '+') goto yy40;
@@ -868,7 +867,7 @@ yy41:
        yych = *++YYCURSOR;
        if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 628 "ext/standard/var_unserializer.re"
+#line 633 "ext/standard/var_unserializer.re"
        {
        size_t len, maxlen;
        char *str;
@@ -890,6 +889,12 @@ yy41:
                return 0;
        }
 
+       if (*(YYCURSOR + 1) != ';') {
+               efree(str);
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+
        YYCURSOR += 2;
        *p = YYCURSOR;
 
@@ -897,7 +902,7 @@ yy41:
        ZVAL_STRINGL(*rval, str, len, 0);
        return 1;
 }
-#line 901 "ext/standard/var_unserializer.c"
+#line 906 "ext/standard/var_unserializer.c"
 yy46:
        yych = *++YYCURSOR;
        if (yych == '+') goto yy47;
@@ -939,6 +944,11 @@ yy48:
                return 0;
        }
 
+       if (*(YYCURSOR + 1) != ';') {
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+
        YYCURSOR += 2;
        *p = YYCURSOR;
 
@@ -946,7 +956,7 @@ yy48:
        ZVAL_STRINGL(*rval, str, len, 1);
        return 1;
 }
-#line 950 "ext/standard/var_unserializer.c"
+#line 960 "ext/standard/var_unserializer.c"
 yy53:
        yych = *++YYCURSOR;
        if (yych <= '/') {
@@ -1044,7 +1054,7 @@ use_double:
        ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
        return 1;
 }
-#line 1048 "ext/standard/var_unserializer.c"
+#line 1058 "ext/standard/var_unserializer.c"
 yy65:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1118,7 +1128,7 @@ yy73:
 
        return 1;
 }
-#line 1122 "ext/standard/var_unserializer.c"
+#line 1132 "ext/standard/var_unserializer.c"
 yy76:
        yych = *++YYCURSOR;
        if (yych == 'N') goto yy73;
@@ -1172,7 +1182,7 @@ yy79:
        ZVAL_LONG(*rval, parse_iv(start + 2));
        return 1;
 }
-#line 1176 "ext/standard/var_unserializer.c"
+#line 1186 "ext/standard/var_unserializer.c"
 yy83:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
@@ -1187,7 +1197,7 @@ yy83:
        ZVAL_BOOL(*rval, parse_iv(start + 2));
        return 1;
 }
-#line 1191 "ext/standard/var_unserializer.c"
+#line 1201 "ext/standard/var_unserializer.c"
 yy87:
        ++YYCURSOR;
 #line 534 "ext/standard/var_unserializer.re"
@@ -1197,7 +1207,7 @@ yy87:
        ZVAL_NULL(*rval);
        return 1;
 }
-#line 1201 "ext/standard/var_unserializer.c"
+#line 1211 "ext/standard/var_unserializer.c"
 yy89:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1243,7 +1253,7 @@ yy91:
 
        return 1;
 }
-#line 1247 "ext/standard/var_unserializer.c"
+#line 1257 "ext/standard/var_unserializer.c"
 yy95:
        yych = *++YYCURSOR;
        if (yych <= ',') {
@@ -1287,9 +1297,9 @@ yy97:
 
        return 1;
 }
-#line 1291 "ext/standard/var_unserializer.c"
+#line 1301 "ext/standard/var_unserializer.c"
 }
-#line 842 "ext/standard/var_unserializer.re"
+#line 853 "ext/standard/var_unserializer.re"
 
 
        return 0;
index 7a48977c26a1b6ef2dc92020676c6c560f443a66..d1d4ef98e4790c8722d1b08abcfa0827c3813386 100644 (file)
@@ -617,6 +617,11 @@ use_double:
                return 0;
        }
 
+       if (*(YYCURSOR + 1) != ';') {
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+
        YYCURSOR += 2;
        *p = YYCURSOR;
 
@@ -646,6 +651,12 @@ use_double:
                return 0;
        }
 
+       if (*(YYCURSOR + 1) != ';') {
+               efree(str);
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+
        YYCURSOR += 2;
        *p = YYCURSOR;