]> granicus.if.org Git - php/commitdiff
Fixed bug #74111
authorNikita Popov <nikita.ppv@gmail.com>
Sun, 25 Jun 2017 19:15:26 +0000 (21:15 +0200)
committerStanislav Malyshev <stas@php.net>
Wed, 5 Jul 2017 02:06:16 +0000 (19:06 -0700)
ext/standard/tests/serialize/bug25378.phpt
ext/standard/tests/serialize/bug74111.phpt [new file with mode: 0644]
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

index e865b96e9935f281967a8feb3b1cca373b6364b8..e95a42700620176cb256a28f7f781090b1c407c0 100644 (file)
@@ -42,7 +42,7 @@ bool(false)
 Notice: unserialize(): Error at offset 17 of 33 bytes in %sbug25378.php on line %d
 bool(false)
 
-Notice: unserialize(): Error at offset 33 of 32 bytes in %sbug25378.php on line %d
+Notice: unserialize(): Error at offset 32 of 32 bytes in %sbug25378.php on line %d
 bool(false)
 
 Notice: unserialize(): Error at offset 2 of 13 bytes in %sbug25378.php on line %d
diff --git a/ext/standard/tests/serialize/bug74111.phpt b/ext/standard/tests/serialize/bug74111.phpt
new file mode 100644 (file)
index 0000000..62922be
--- /dev/null
@@ -0,0 +1,10 @@
+--TEST--
+Bug #74111: Heap buffer overread (READ: 1) finish_nested_data from unserialize
+--FILE--
+<?php
+$s = 'O:8:"stdClass":00000000';
+var_dump(unserialize($s));
+?>
+--EXPECTF--
+Notice: unserialize(): Error at offset 25 of 23 bytes in %s on line %d
+bool(false)
index 6706866f2bcc64453ff049957364ba137f94257f..f94d1763bbf1d6de92cea31683e9927eac23186f 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 */
+/* Generated by re2c 0.15.3 */
 #line 1 "ext/standard/var_unserializer.re"
 /*
   +----------------------------------------------------------------------+
@@ -406,13 +406,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
 
 static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
 {
-       if (*((*p)++) == '}')
-               return 1;
+       if (*p >= max || **p != '}') {
+               return 0;
+       }
 
-#if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
-       zval_ptr_dtor(rval);
-#endif
-       return 0;
+       (*p)++;
+       return 1;
 }
 
 static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
@@ -529,7 +528,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
 
 
 
-#line 533 "ext/standard/var_unserializer.c"
+#line 532 "ext/standard/var_unserializer.c"
 {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
@@ -570,407 +569,539 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
        yych = *YYCURSOR;
        switch (yych) {
        case 'C':
-       case 'O':       goto yy4;
+       case 'O':       goto yy13;
        case 'N':       goto yy5;
-       case 'R':       goto yy6;
-       case 'S':       goto yy7;
-       case 'a':       goto yy8;
-       case 'b':       goto yy9;
-       case 'd':       goto yy10;
-       case 'i':       goto yy11;
+       case 'R':       goto yy2;
+       case 'S':       goto yy10;
+       case 'a':       goto yy11;
+       case 'b':       goto yy6;
+       case 'd':       goto yy8;
+       case 'i':       goto yy7;
        case 'o':       goto yy12;
-       case 'r':       goto yy13;
-       case 's':       goto yy14;
-       case '}':       goto yy15;
-       default:        goto yy2;
+       case 'r':       goto yy4;
+       case 's':       goto yy9;
+       case '}':       goto yy14;
+       default:        goto yy16;
        }
 yy2:
-       ++YYCURSOR;
+       yych = *(YYMARKER = ++YYCURSOR);
+       if (yych == ':') goto yy95;
 yy3:
-#line 909 "ext/standard/var_unserializer.re"
+#line 908 "ext/standard/var_unserializer.re"
        { return 0; }
 #line 593 "ext/standard/var_unserializer.c"
 yy4:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy17;
+       if (yych == ':') goto yy89;
        goto yy3;
 yy5:
        yych = *++YYCURSOR;
-       if (yych == ';') goto yy19;
+       if (yych == ';') goto yy87;
        goto yy3;
 yy6:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy21;
+       if (yych == ':') goto yy83;
        goto yy3;
 yy7:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy22;
+       if (yych == ':') goto yy77;
        goto yy3;
 yy8:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy23;
+       if (yych == ':') goto yy53;
        goto yy3;
 yy9:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy24;
+       if (yych == ':') goto yy46;
        goto yy3;
 yy10:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy25;
+       if (yych == ':') goto yy39;
        goto yy3;
 yy11:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy26;
+       if (yych == ':') goto yy32;
        goto yy3;
 yy12:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy27;
+       if (yych == ':') goto yy25;
        goto yy3;
 yy13:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy28;
+       if (yych == ':') goto yy17;
        goto yy3;
 yy14:
-       yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy29;
-       goto yy3;
-yy15:
        ++YYCURSOR;
-#line 903 "ext/standard/var_unserializer.re"
+#line 902 "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 646 "ext/standard/var_unserializer.c"
+#line 642 "ext/standard/var_unserializer.c"
+yy16:
+       yych = *++YYCURSOR;
+       goto yy3;
 yy17:
        yych = *++YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy31;
+               goto yy20;
        }
-       if (yych == '+') goto yy30;
+       if (yych == '+') goto yy19;
 yy18:
        YYCURSOR = YYMARKER;
        goto yy3;
 yy19:
-       ++YYCURSOR;
-#line 581 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-       INIT_PZVAL(*rval);
-       ZVAL_NULL(*rval);
-       return 1;
-}
-#line 665 "ext/standard/var_unserializer.c"
-yy21:
        yych = *++YYCURSOR;
-       if (yych <= ',') {
-               if (yych == '+') goto yy33;
-               goto yy18;
-       } else {
-               if (yych <= '-') goto yy33;
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy34;
-               goto yy18;
+       if (yybm[0+yych] & 128) {
+               goto yy20;
        }
-yy22:
-       yych = *++YYCURSOR;
-       if (yych == '+') goto yy36;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy37;
-       goto yy18;
-yy23:
-       yych = *++YYCURSOR;
-       if (yych == '+') goto yy39;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy40;
        goto yy18;
-yy24:
-       yych = *++YYCURSOR;
+yy20:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yybm[0+yych] & 128) {
+               goto yy20;
+       }
        if (yych <= '/') goto yy18;
-       if (yych <= '1') goto yy42;
-       goto yy18;
-yy25:
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych <= '/') {
-               if (yych <= ',') {
-                       if (yych == '+') goto yy43;
-                       goto yy18;
-               } else {
-                       if (yych <= '-') goto yy44;
-                       if (yych <= '.') goto yy45;
-                       goto yy18;
+       if (yych != '"') goto yy18;
+       ++YYCURSOR;
+#line 748 "ext/standard/var_unserializer.re"
+       {
+       size_t len, len2, len3, maxlen;
+       long elements;
+       char *class_name;
+       zend_class_entry *ce;
+       zend_class_entry **pce;
+       int incomplete_class = 0;
+
+       int custom_object = 0;
+
+       zval *user_func;
+       zval *retval_ptr;
+       zval **args[1];
+       zval *arg_func_name;
+
+    if (!var_hash) return 0;
+       if (*start == 'C') {
+               custom_object = 1;
+       }
+
+       INIT_PZVAL(*rval);
+       len2 = len = parse_uiv(start + 2);
+       maxlen = max - YYCURSOR;
+       if (maxlen < len || len == 0) {
+               *p = start + 2;
+               return 0;
+       }
+
+       class_name = (char*)YYCURSOR;
+
+       YYCURSOR += len;
+
+       if (*(YYCURSOR) != '"') {
+               *p = YYCURSOR;
+               return 0;
+       }
+       if (*(YYCURSOR+1) != ':') {
+               *p = YYCURSOR+1;
+               return 0;
+       }
+
+       len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
+       if (len3 != len)
+       {
+               *p = YYCURSOR + len3 - len;
+               return 0;
+       }
+
+       class_name = estrndup(class_name, len);
+
+       do {
+               /* Try to find class directly */
+               BG(serialize_lock)++;
+               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
+                       BG(serialize_lock)--;
+                       if (EG(exception)) {
+                               efree(class_name);
+                               return 0;
+                       }
+                       ce = *pce;
+                       break;
                }
-       } else {
-               if (yych <= 'I') {
-                       if (yych <= '9') goto yy46;
-                       if (yych <= 'H') goto yy18;
-                       goto yy48;
+               BG(serialize_lock)--;
+
+               if (EG(exception)) {
+                       efree(class_name);
+                       return 0;
+               }
+
+               /* Check for unserialize callback */
+               if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
+                       incomplete_class = 1;
+                       ce = PHP_IC_ENTRY;
+                       break;
+               }
+
+               /* Call unserialize callback */
+               MAKE_STD_ZVAL(user_func);
+               ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
+               args[0] = &arg_func_name;
+               MAKE_STD_ZVAL(arg_func_name);
+               ZVAL_STRING(arg_func_name, class_name, 1);
+               BG(serialize_lock)++;
+               if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
+                       BG(serialize_lock)--;
+                       if (EG(exception)) {
+                               efree(class_name);
+                               zval_ptr_dtor(&user_func);
+                               zval_ptr_dtor(&arg_func_name);
+                               return 0;
+                       }
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
+                       incomplete_class = 1;
+                       ce = PHP_IC_ENTRY;
+                       zval_ptr_dtor(&user_func);
+                       zval_ptr_dtor(&arg_func_name);
+                       break;
+               }
+               BG(serialize_lock)--;
+               if (retval_ptr) {
+                       zval_ptr_dtor(&retval_ptr);
+               }
+               if (EG(exception)) {
+                       efree(class_name);
+                       zval_ptr_dtor(&user_func);
+                       zval_ptr_dtor(&arg_func_name);
+                       return 0;
+               }
+
+               /* The callback function may have defined the class */
+               BG(serialize_lock)++;
+               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
+                       ce = *pce;
                } else {
-                       if (yych == 'N') goto yy49;
-                       goto yy18;
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
+                       incomplete_class = 1;
+                       ce = PHP_IC_ENTRY;
+               }
+               BG(serialize_lock)--;
+
+               zval_ptr_dtor(&user_func);
+               zval_ptr_dtor(&arg_func_name);
+               break;
+       } while (1);
+
+       *p = YYCURSOR;
+
+       if (custom_object) {
+               int ret;
+
+               ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
+
+               if (ret && incomplete_class) {
+                       php_store_class_name(*rval, class_name, len2);
                }
+               efree(class_name);
+               return ret;
        }
-yy26:
-       yych = *++YYCURSOR;
-       if (yych <= ',') {
-               if (yych == '+') goto yy50;
-               goto yy18;
-       } else {
-               if (yych <= '-') goto yy50;
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy51;
-               goto yy18;
+
+       elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
+
+       if (elements < 0) {
+          efree(class_name);
+          return 0;
        }
-yy27:
-       yych = *++YYCURSOR;
-       if (yych <= ',') {
-               if (yych == '+') goto yy53;
-               goto yy18;
-       } else {
-               if (yych <= '-') goto yy53;
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy54;
-               goto yy18;
+
+       if (incomplete_class) {
+               php_store_class_name(*rval, class_name, len2);
        }
-yy28:
+       efree(class_name);
+
+       return object_common2(UNSERIALIZE_PASSTHRU, elements);
+}
+#line 827 "ext/standard/var_unserializer.c"
+yy25:
        yych = *++YYCURSOR;
        if (yych <= ',') {
-               if (yych == '+') goto yy56;
-               goto yy18;
+               if (yych != '+') goto yy18;
        } else {
-               if (yych <= '-') goto yy56;
+               if (yych <= '-') goto yy26;
                if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy57;
+               if (yych <= '9') goto yy27;
                goto yy18;
        }
-yy29:
+yy26:
        yych = *++YYCURSOR;
-       if (yych == '+') goto yy59;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy60;
-       goto yy18;
-yy30:
-       yych = *++YYCURSOR;
-       if (yybm[0+yych] & 128) {
-               goto yy31;
-       }
-       goto yy18;
-yy31:
+       if (yych >= ':') goto yy18;
+yy27:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
-       if (yybm[0+yych] & 128) {
-               goto yy31;
-       }
        if (yych <= '/') goto yy18;
-       if (yych <= ':') goto yy62;
-       goto yy18;
-yy33:
+       if (yych <= '9') goto yy27;
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
-yy34:
+       if (yych != '"') goto yy18;
        ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
+#line 735 "ext/standard/var_unserializer.re"
+       {
+       long elements;
+    if (!var_hash) return 0;
+
+       INIT_PZVAL(*rval);
+
+       elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
+       if (elements < 0) {
+               return 0;
+       }
+       return object_common2(UNSERIALIZE_PASSTHRU, elements);
+}
+#line 865 "ext/standard/var_unserializer.c"
+yy32:
+       yych = *++YYCURSOR;
+       if (yych == '+') goto yy33;
        if (yych <= '/') goto yy18;
        if (yych <= '9') goto yy34;
-       if (yych == ';') goto yy63;
        goto yy18;
-yy36:
+yy33:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
        if (yych >= ':') goto yy18;
-yy37:
+yy34:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy37;
-       if (yych <= ':') goto yy65;
-       goto yy18;
-yy39:
+       if (yych <= '9') goto yy34;
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
-yy40:
+       if (yych != '{') goto yy18;
        ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy40;
-       if (yych <= ':') goto yy66;
-       goto yy18;
-yy42:
-       yych = *++YYCURSOR;
-       if (yych == ';') goto yy67;
-       goto yy18;
-yy43:
-       yych = *++YYCURSOR;
-       if (yych == '.') goto yy45;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy46;
-       goto yy18;
-yy44:
-       yych = *++YYCURSOR;
-       if (yych <= '/') {
-               if (yych != '.') goto yy18;
-       } else {
-               if (yych <= '9') goto yy46;
-               if (yych == 'I') goto yy48;
-               goto yy18;
+#line 714 "ext/standard/var_unserializer.re"
+       {
+       long elements = parse_iv(start + 2);
+       /* use iv() not uiv() in order to check data range */
+       *p = YYCURSOR;
+    if (!var_hash) return 0;
+
+       if (elements < 0) {
+               return 0;
        }
-yy45:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy69;
-       goto yy18;
-yy46:
-       ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
-       yych = *YYCURSOR;
-       if (yych <= ':') {
-               if (yych <= '.') {
-                       if (yych <= '-') goto yy18;
-                       goto yy69;
-               } else {
-                       if (yych <= '/') goto yy18;
-                       if (yych <= '9') goto yy46;
-                       goto yy18;
-               }
-       } else {
-               if (yych <= 'E') {
-                       if (yych <= ';') goto yy71;
-                       if (yych <= 'D') goto yy18;
-                       goto yy73;
-               } else {
-                       if (yych == 'e') goto yy73;
-                       goto yy18;
-               }
+
+       INIT_PZVAL(*rval);
+
+       array_init_size(*rval, elements);
+
+       if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
+               return 0;
        }
-yy48:
-       yych = *++YYCURSOR;
-       if (yych == 'N') goto yy74;
-       goto yy18;
-yy49:
-       yych = *++YYCURSOR;
-       if (yych == 'A') goto yy75;
-       goto yy18;
-yy50:
+
+       return finish_nested_data(UNSERIALIZE_PASSTHRU);
+}
+#line 907 "ext/standard/var_unserializer.c"
+yy39:
        yych = *++YYCURSOR;
+       if (yych == '+') goto yy40;
        if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
-yy51:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy51;
-       if (yych == ';') goto yy76;
+       if (yych <= '9') goto yy41;
        goto yy18;
-yy53:
+yy40:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
        if (yych >= ':') goto yy18;
-yy54:
+yy41:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy54;
-       if (yych <= ':') goto yy78;
-       goto yy18;
-yy56:
+       if (yych <= '9') goto yy41;
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
-yy57:
+       if (yych != '"') goto yy18;
        ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
+#line 679 "ext/standard/var_unserializer.re"
+       {
+       size_t len, maxlen;
+       char *str;
+
+       len = parse_uiv(start + 2);
+       maxlen = max - YYCURSOR;
+       if (maxlen < len) {
+               *p = start + 2;
+               return 0;
+       }
+
+       if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
+               return 0;
+       }
+
+       if (*(YYCURSOR) != '"') {
+               efree(str);
+               *p = YYCURSOR;
+               return 0;
+       }
+
+       if (*(YYCURSOR + 1) != ';') {
+               efree(str);
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+
+       YYCURSOR += 2;
+       *p = YYCURSOR;
+
+       INIT_PZVAL(*rval);
+       ZVAL_STRINGL(*rval, str, len, 0);
+       return 1;
+}
+#line 963 "ext/standard/var_unserializer.c"
+yy46:
+       yych = *++YYCURSOR;
+       if (yych == '+') goto yy47;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy57;
-       if (yych == ';') goto yy79;
+       if (yych <= '9') goto yy48;
        goto yy18;
-yy59:
+yy47:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
        if (yych >= ':') goto yy18;
-yy60:
+yy48:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy60;
-       if (yych <= ':') goto yy81;
-       goto yy18;
-yy62:
+       if (yych <= '9') goto yy48;
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych == '"') goto yy82;
-       goto yy18;
-yy63:
+       if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 537 "ext/standard/var_unserializer.re"
+#line 646 "ext/standard/var_unserializer.re"
        {
-       long id;
+       size_t len, maxlen;
+       char *str;
 
-       *p = YYCURSOR;
-       if (!var_hash) return 0;
+       len = parse_uiv(start + 2);
+       maxlen = max - YYCURSOR;
+       if (maxlen < len) {
+               *p = start + 2;
+               return 0;
+       }
 
-       id = parse_iv(start + 2) - 1;
-       if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+       str = (char*)YYCURSOR;
+
+       YYCURSOR += len;
+
+       if (*(YYCURSOR) != '"') {
+               *p = YYCURSOR;
                return 0;
        }
 
-       if (*rval != NULL) {
-               var_push_dtor_no_addref(var_hash, rval);
+       if (*(YYCURSOR + 1) != ';') {
+               *p = YYCURSOR + 1;
+               return 0;
        }
-       *rval = *rval_ref;
-       Z_ADDREF_PP(rval);
-       Z_SET_ISREF_PP(rval);
 
+       YYCURSOR += 2;
+       *p = YYCURSOR;
+
+       INIT_PZVAL(*rval);
+       ZVAL_STRINGL(*rval, str, len, 1);
        return 1;
 }
-#line 936 "ext/standard/var_unserializer.c"
-yy65:
+#line 1017 "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;
+               }
+       }
        yych = *++YYCURSOR;
-       if (yych == '"') goto yy84;
+       if (yych == 'A') goto yy76;
        goto yy18;
-yy66:
+yy55:
+       yych = *++YYCURSOR;
+       if (yych <= '/') {
+               if (yych == '.') goto yy60;
+               goto yy18;
+       } else {
+               if (yych <= '9') goto yy58;
+               if (yych != 'I') goto yy18;
+       }
+yy56:
        yych = *++YYCURSOR;
-       if (yych == '{') goto yy86;
+       if (yych == 'N') goto yy72;
        goto yy18;
-yy67:
+yy57:
+       yych = *++YYCURSOR;
+       if (yych == '.') goto yy60;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+yy58:
        ++YYCURSOR;
-#line 588 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-       INIT_PZVAL(*rval);
-       ZVAL_BOOL(*rval, parse_iv(start + 2));
-       return 1;
-}
-#line 954 "ext/standard/var_unserializer.c"
-yy69:
+       if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+       yych = *YYCURSOR;
+       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;
+               }
+       }
+yy60:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+yy61:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
        yych = *YYCURSOR;
        if (yych <= ';') {
                if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy69;
+               if (yych <= '9') goto yy61;
                if (yych <= ':') goto yy18;
        } else {
                if (yych <= 'E') {
                        if (yych <= 'D') goto yy18;
-                       goto yy73;
+                       goto yy65;
                } else {
-                       if (yych == 'e') goto yy73;
+                       if (yych == 'e') goto yy65;
                        goto yy18;
                }
        }
-yy71:
+yy63:
        ++YYCURSOR;
-#line 637 "ext/standard/var_unserializer.re"
+#line 636 "ext/standard/var_unserializer.re"
        {
 #if SIZEOF_LONG == 4
 use_double:
@@ -980,408 +1111,252 @@ use_double:
        ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
        return 1;
 }
-#line 984 "ext/standard/var_unserializer.c"
-yy73:
+#line 1115 "ext/standard/var_unserializer.c"
+yy65:
        yych = *++YYCURSOR;
        if (yych <= ',') {
-               if (yych == '+') goto yy88;
-               goto yy18;
+               if (yych != '+') goto yy18;
        } else {
-               if (yych <= '-') goto yy88;
+               if (yych <= '-') goto yy66;
                if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy89;
+               if (yych <= '9') goto yy67;
                goto yy18;
        }
-yy74:
+yy66:
        yych = *++YYCURSOR;
-       if (yych == 'F') goto yy91;
+       if (yych <= ',') {
+               if (yych == '+') goto yy69;
+               goto yy18;
+       } else {
+               if (yych <= '-') goto yy69;
+               if (yych <= '/') goto yy18;
+               if (yych >= ':') goto yy18;
+       }
+yy67:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych <= '9') goto yy67;
+       if (yych == ';') goto yy63;
        goto yy18;
-yy75:
+yy69:
        yych = *++YYCURSOR;
-       if (yych == 'N') goto yy91;
+       if (yych <= '/') goto yy18;
+       if (yych <= '9') goto yy67;
        goto yy18;
-yy76:
+yy70:
        ++YYCURSOR;
-#line 595 "ext/standard/var_unserializer.re"
-       {
-#if SIZEOF_LONG == 4
-       int digits = YYCURSOR - start - 3;
-
-       if (start[2] == '-' || start[2] == '+') {
-               digits--;
-       }
-
-       /* Use double for large long values that were serialized on a 64-bit system */
-       if (digits >= MAX_LENGTH_OF_LONG - 1) {
-               if (digits == MAX_LENGTH_OF_LONG - 1) {
-                       int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
-
-                       if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
-                               goto use_double;
-                       }
+       if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+       yych = *YYCURSOR;
+       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 {
-                       goto use_double;
+                       if (yych == 'e') goto yy65;
+                       goto yy18;
                }
        }
-#endif
-       *p = YYCURSOR;
-       INIT_PZVAL(*rval);
-       ZVAL_LONG(*rval, parse_iv(start + 2));
-       return 1;
-}
-#line 1033 "ext/standard/var_unserializer.c"
-yy78:
+yy72:
        yych = *++YYCURSOR;
-       if (yych == '"') goto yy92;
-       goto yy18;
-yy79:
+       if (yych != 'F') goto yy18;
+yy73:
+       yych = *++YYCURSOR;
+       if (yych != ';') goto yy18;
        ++YYCURSOR;
-#line 558 "ext/standard/var_unserializer.re"
+#line 621 "ext/standard/var_unserializer.re"
        {
-       long id;
+       *p = YYCURSOR;
+       INIT_PZVAL(*rval);
 
-       *p = YYCURSOR;
-       if (!var_hash) return 0;
-
-       id = parse_iv(start + 2) - 1;
-       if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
-               return 0;
-       }
-
-       if (*rval == *rval_ref) return 0;
-
-       if (*rval != NULL) {
-               var_push_dtor_no_addref(var_hash, rval);
+       if (!strncmp(start + 2, "NAN", 3)) {
+               ZVAL_DOUBLE(*rval, php_get_nan());
+       } else if (!strncmp(start + 2, "INF", 3)) {
+               ZVAL_DOUBLE(*rval, php_get_inf());
+       } else if (!strncmp(start + 2, "-INF", 4)) {
+               ZVAL_DOUBLE(*rval, -php_get_inf());
        }
-       *rval = *rval_ref;
-       Z_ADDREF_PP(rval);
-       Z_UNSET_ISREF_PP(rval);
 
        return 1;
 }
-#line 1063 "ext/standard/var_unserializer.c"
-yy81:
+#line 1189 "ext/standard/var_unserializer.c"
+yy76:
        yych = *++YYCURSOR;
-       if (yych == '"') goto yy94;
+       if (yych == 'N') goto yy73;
        goto yy18;
-yy82:
+yy77:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
+               if (yych != '+') goto yy18;
+       } 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;
+yy79:
        ++YYCURSOR;
-#line 749 "ext/standard/var_unserializer.re"
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych <= '9') goto yy79;
+       if (yych != ';') goto yy18;
+       ++YYCURSOR;
+#line 594 "ext/standard/var_unserializer.re"
        {
-       size_t len, len2, len3, maxlen;
-       long elements;
-       char *class_name;
-       zend_class_entry *ce;
-       zend_class_entry **pce;
-       int incomplete_class = 0;
-
-       int custom_object = 0;
-
-       zval *user_func;
-       zval *retval_ptr;
-       zval **args[1];
-       zval *arg_func_name;
-
-    if (!var_hash) return 0;
-       if (*start == 'C') {
-               custom_object = 1;
-       }
-
-       INIT_PZVAL(*rval);
-       len2 = len = parse_uiv(start + 2);
-       maxlen = max - YYCURSOR;
-       if (maxlen < len || len == 0) {
-               *p = start + 2;
-               return 0;
-       }
-
-       class_name = (char*)YYCURSOR;
-
-       YYCURSOR += len;
-
-       if (*(YYCURSOR) != '"') {
-               *p = YYCURSOR;
-               return 0;
-       }
-       if (*(YYCURSOR+1) != ':') {
-               *p = YYCURSOR+1;
-               return 0;
-       }
+#if SIZEOF_LONG == 4
+       int digits = YYCURSOR - start - 3;
 
-       len3 = strspn(class_name, "0123456789_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377\\");
-       if (len3 != len)
-       {
-               *p = YYCURSOR + len3 - len;
-               return 0;
+       if (start[2] == '-' || start[2] == '+') {
+               digits--;
        }
 
-       class_name = estrndup(class_name, len);
-
-       do {
-               /* Try to find class directly */
-               BG(serialize_lock)++;
-               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
-                       BG(serialize_lock)--;
-                       if (EG(exception)) {
-                               efree(class_name);
-                               return 0;
-                       }
-                       ce = *pce;
-                       break;
-               }
-               BG(serialize_lock)--;
-
-               if (EG(exception)) {
-                       efree(class_name);
-                       return 0;
-               }
-
-               /* Check for unserialize callback */
-               if ((PG(unserialize_callback_func) == NULL) || (PG(unserialize_callback_func)[0] == '\0')) {
-                       incomplete_class = 1;
-                       ce = PHP_IC_ENTRY;
-                       break;
-               }
+       /* Use double for large long values that were serialized on a 64-bit system */
+       if (digits >= MAX_LENGTH_OF_LONG - 1) {
+               if (digits == MAX_LENGTH_OF_LONG - 1) {
+                       int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
 
-               /* Call unserialize callback */
-               MAKE_STD_ZVAL(user_func);
-               ZVAL_STRING(user_func, PG(unserialize_callback_func), 1);
-               args[0] = &arg_func_name;
-               MAKE_STD_ZVAL(arg_func_name);
-               ZVAL_STRING(arg_func_name, class_name, 1);
-               BG(serialize_lock)++;
-               if (call_user_function_ex(CG(function_table), NULL, user_func, &retval_ptr, 1, args, 0, NULL TSRMLS_CC) != SUCCESS) {
-                       BG(serialize_lock)--;
-                       if (EG(exception)) {
-                               efree(class_name);
-                               zval_ptr_dtor(&user_func);
-                               zval_ptr_dtor(&arg_func_name);
-                               return 0;
+                       if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
+                               goto use_double;
                        }
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "defined (%s) but not found", user_func->value.str.val);
-                       incomplete_class = 1;
-                       ce = PHP_IC_ENTRY;
-                       zval_ptr_dtor(&user_func);
-                       zval_ptr_dtor(&arg_func_name);
-                       break;
-               }
-               BG(serialize_lock)--;
-               if (retval_ptr) {
-                       zval_ptr_dtor(&retval_ptr);
-               }
-               if (EG(exception)) {
-                       efree(class_name);
-                       zval_ptr_dtor(&user_func);
-                       zval_ptr_dtor(&arg_func_name);
-                       return 0;
-               }
-
-               /* The callback function may have defined the class */
-               BG(serialize_lock)++;
-               if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
-                       ce = *pce;
                } else {
-                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Function %s() hasn't defined the class it was called for", user_func->value.str.val);
-                       incomplete_class = 1;
-                       ce = PHP_IC_ENTRY;
-               }
-               BG(serialize_lock)--;
-
-               zval_ptr_dtor(&user_func);
-               zval_ptr_dtor(&arg_func_name);
-               break;
-       } while (1);
-
-       *p = YYCURSOR;
-
-       if (custom_object) {
-               int ret;
-
-               ret = object_custom(UNSERIALIZE_PASSTHRU, ce);
-
-               if (ret && incomplete_class) {
-                       php_store_class_name(*rval, class_name, len2);
+                       goto use_double;
                }
-               efree(class_name);
-               return ret;
-       }
-
-       elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
-
-       if (elements < 0) {
-          efree(class_name);
-          return 0;
-       }
-
-       if (incomplete_class) {
-               php_store_class_name(*rval, class_name, len2);
        }
-       efree(class_name);
-
-       return object_common2(UNSERIALIZE_PASSTHRU, elements);
+#endif
+       *p = YYCURSOR;
+       INIT_PZVAL(*rval);
+       ZVAL_LONG(*rval, parse_iv(start + 2));
+       return 1;
 }
-#line 1224 "ext/standard/var_unserializer.c"
-yy84:
+#line 1243 "ext/standard/var_unserializer.c"
+yy83:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= '2') goto yy18;
+       yych = *++YYCURSOR;
+       if (yych != ';') goto yy18;
        ++YYCURSOR;
-#line 680 "ext/standard/var_unserializer.re"
+#line 587 "ext/standard/var_unserializer.re"
        {
-       size_t len, maxlen;
-       char *str;
-
-       len = parse_uiv(start + 2);
-       maxlen = max - YYCURSOR;
-       if (maxlen < len) {
-               *p = start + 2;
-               return 0;
-       }
-
-       if ((str = unserialize_str(&YYCURSOR, &len, maxlen)) == NULL) {
-               return 0;
-       }
-
-       if (*(YYCURSOR) != '"') {
-               efree(str);
-               *p = YYCURSOR;
-               return 0;
-       }
-
-       if (*(YYCURSOR + 1) != ';') {
-               efree(str);
-               *p = YYCURSOR + 1;
-               return 0;
-       }
-
-       YYCURSOR += 2;
        *p = YYCURSOR;
-
        INIT_PZVAL(*rval);
-       ZVAL_STRINGL(*rval, str, len, 0);
+       ZVAL_BOOL(*rval, parse_iv(start + 2));
        return 1;
 }
-#line 1262 "ext/standard/var_unserializer.c"
-yy86:
+#line 1258 "ext/standard/var_unserializer.c"
+yy87:
        ++YYCURSOR;
-#line 715 "ext/standard/var_unserializer.re"
+#line 580 "ext/standard/var_unserializer.re"
        {
-       long elements = parse_iv(start + 2);
-       /* use iv() not uiv() in order to check data range */
        *p = YYCURSOR;
-    if (!var_hash) return 0;
-
-       if (elements < 0) {
-               return 0;
-       }
-
        INIT_PZVAL(*rval);
-
-       array_init_size(*rval, elements);
-
-       if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
-               return 0;
-       }
-
-       return finish_nested_data(UNSERIALIZE_PASSTHRU);
+       ZVAL_NULL(*rval);
+       return 1;
 }
-#line 1286 "ext/standard/var_unserializer.c"
-yy88:
+#line 1268 "ext/standard/var_unserializer.c"
+yy89:
        yych = *++YYCURSOR;
        if (yych <= ',') {
-               if (yych == '+') goto yy96;
-               goto yy18;
+               if (yych != '+') goto yy18;
        } else {
-               if (yych <= '-') goto yy96;
+               if (yych <= '-') goto yy90;
                if (yych <= '/') goto yy18;
-               if (yych >= ':') goto yy18;
+               if (yych <= '9') goto yy91;
+               goto yy18;
        }
-yy89:
+yy90:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+yy91:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy89;
-       if (yych == ';') goto yy71;
-       goto yy18;
-yy91:
-       yych = *++YYCURSOR;
-       if (yych == ';') goto yy97;
-       goto yy18;
-yy92:
+       if (yych <= '9') goto yy91;
+       if (yych != ';') goto yy18;
        ++YYCURSOR;
-#line 736 "ext/standard/var_unserializer.re"
+#line 557 "ext/standard/var_unserializer.re"
        {
-       long elements;
-    if (!var_hash) return 0;
-
-       INIT_PZVAL(*rval);
+       long id;
 
-       elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
-       if (elements < 0) {
-               return 0;
-       }
-       return object_common2(UNSERIALIZE_PASSTHRU, elements);
-}
-#line 1324 "ext/standard/var_unserializer.c"
-yy94:
-       ++YYCURSOR;
-#line 647 "ext/standard/var_unserializer.re"
-       {
-       size_t len, maxlen;
-       char *str;
+       *p = YYCURSOR;
+       if (!var_hash) return 0;
 
-       len = parse_uiv(start + 2);
-       maxlen = max - YYCURSOR;
-       if (maxlen < len) {
-               *p = start + 2;
+       id = parse_iv(start + 2) - 1;
+       if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
                return 0;
        }
 
-       str = (char*)YYCURSOR;
-
-       YYCURSOR += len;
-
-       if (*(YYCURSOR) != '"') {
-               *p = YYCURSOR;
-               return 0;
-       }
+       if (*rval == *rval_ref) return 0;
 
-       if (*(YYCURSOR + 1) != ';') {
-               *p = YYCURSOR + 1;
-               return 0;
+       if (*rval != NULL) {
+               var_push_dtor_no_addref(var_hash, rval);
        }
+       *rval = *rval_ref;
+       Z_ADDREF_PP(rval);
+       Z_UNSET_ISREF_PP(rval);
 
-       YYCURSOR += 2;
-       *p = YYCURSOR;
-
-       INIT_PZVAL(*rval);
-       ZVAL_STRINGL(*rval, str, len, 1);
        return 1;
 }
-#line 1360 "ext/standard/var_unserializer.c"
+#line 1314 "ext/standard/var_unserializer.c"
+yy95:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
+               if (yych != '+') goto yy18;
+       } 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 <= '9') goto yy89;
-       goto yy18;
+       if (yych >= ':') goto yy18;
 yy97:
        ++YYCURSOR;
-#line 622 "ext/standard/var_unserializer.re"
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych <= '9') goto yy97;
+       if (yych != ';') goto yy18;
+       ++YYCURSOR;
+#line 536 "ext/standard/var_unserializer.re"
        {
-       *p = YYCURSOR;
-       INIT_PZVAL(*rval);
+       long id;
 
-       if (!strncmp(start + 2, "NAN", 3)) {
-               ZVAL_DOUBLE(*rval, php_get_nan());
-       } else if (!strncmp(start + 2, "INF", 3)) {
-               ZVAL_DOUBLE(*rval, php_get_inf());
-       } else if (!strncmp(start + 2, "-INF", 4)) {
-               ZVAL_DOUBLE(*rval, -php_get_inf());
+       *p = YYCURSOR;
+       if (!var_hash) return 0;
+
+       id = parse_iv(start + 2) - 1;
+       if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+               return 0;
+       }
+
+       if (*rval != NULL) {
+               var_push_dtor_no_addref(var_hash, rval);
        }
+       *rval = *rval_ref;
+       Z_ADDREF_PP(rval);
+       Z_SET_ISREF_PP(rval);
 
        return 1;
 }
-#line 1383 "ext/standard/var_unserializer.c"
+#line 1358 "ext/standard/var_unserializer.c"
 }
-#line 911 "ext/standard/var_unserializer.re"
+#line 910 "ext/standard/var_unserializer.re"
 
 
        return 0;
index bb0000ba5f4f4d206d32e8615fce3a466f1cecfa..1707ca5cc1eaf34f1a306649eb083c439b6f76c6 100644 (file)
@@ -410,13 +410,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
 
 static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
 {
-       if (*((*p)++) == '}')
-               return 1;
+       if (*p >= max || **p != '}') {
+               return 0;
+       }
 
-#if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
-       zval_ptr_dtor(rval);
-#endif
-       return 0;
+       (*p)++;
+       return 1;
 }
 
 static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)