]> granicus.if.org Git - php/commitdiff
Merge branch 'PHP-7.1' into PHP-7.2
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 12 Aug 2017 11:17:24 +0000 (13:17 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Sat, 12 Aug 2017 11:17:24 +0000 (13:17 +0200)
1  2 
NEWS
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re

diff --cc NEWS
index fb15b6315788e536b2865c6a7374a24746b7b4c2,c783c3c7501c2829205bd83667de6282f94303ad..cd0ce8a9dbcafd9d9c97f6afc80f5f84299141a3
--- 1/NEWS
--- 2/NEWS
+++ b/NEWS
@@@ -1,40 -1,11 +1,46 @@@
  PHP                                                                        NEWS
  |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
 -?? ??? ????, PHP 7.1.9
 +?? ??? ????, PHP 7.2.0beta3
 +
 +- Date:
 +  . Fixed bugĀ #75002 (Null Pointer Dereference in timelib_time_clone). (Derick)
 +
 +- FTP:
 +  . Added ftp_append() function. (blar)
 +
 +- Mbstring:
 +  . Fixed bug #75001 (Wrong reflection on mb_eregi_replace). (Fabien
 +    Villepinte)
 +
 +- SQLite3:
 +  . Updated to SQLite 3.20.0. (cmb)
 +
 +- SPL:
 +  . Fixed bug #75049 (spl_autoload_unregister can't handle
 +    spl_autoload_functions results). (Laruence)
 +  . Added spl_object_id(). (Tyson Andre)
 +
++- Standard:
++  . Fixed bug #74103 (heap-use-after-free when unserializing invalid array
++    size). (Nikita)
++  . Fixed bug #75054 (A Denial of Service Vulnerability was found when
++    performing deserialization). (Nikita)
++
 +- XMLRPC:
 +  . Fixed bug #74975 (Incorrect xmlrpc serialization for classes with declared
 +    properties). (blar)
 +
 +03 Aug 2017, PHP 7.2.0beta2
  
  - Core:
 +  . Implemented FR #74963 (Improved error message on fetching property of
 +    non-object). (Laruence)
    . Fixed bug #74947 (Segfault in scanner on INF number). (Laruence)
    . Fixed bug #74954 (null deref and segfault in zend_generator_resume()). (Bob)
 -  . Fixed bug #74725 (html_errors=1 breaks unhandled exceptions). (Andrea)
 +
 +- CLI:
 +  . Fixed bug #74979 (Interactive shell opening instead of script execution
 +    with -f flag). (Anatol)
  
  - cURL:
    . Fixed bug #74125 (Fixed finding CURL on systems with multiarch support).
index 21a810bb01a7e27ae30bf72d558cb386482a6738,acbc711118e00fb30bd9f2529631bb9a0c86f33e..2c5ea75adbc6273cb6b88d08bcab08046f397f07
@@@ -491,17 -450,8 +491,8 @@@ string_key
                        return 0;
                }
  
-               if (UNEXPECTED(Z_ISUNDEF_P(data))) {
-                       if (Z_TYPE(key) == IS_LONG) {
-                               zend_hash_index_del(ht, Z_LVAL(key));
-                       } else {
-                               zend_hash_del_ind(ht, Z_STR(key));
-                       }
-               } else {
-                       var_push_dtor(var_hash, data);
-               }
+               var_push_dtor(var_hash, data);
 -              zval_dtor(&key);
 +              zval_ptr_dtor(&key);
  
                if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
                        (*p)--;
@@@ -661,7 -611,7 +652,7 @@@ static int php_var_unserialize_internal
        start = cursor;
  
  
- #line 665 "ext/standard/var_unserializer.c"
 -#line 615 "ext/standard/var_unserializer.c"
++#line 656 "ext/standard/var_unserializer.c"
  {
        YYCTYPE yych;
        static const unsigned char yybm[] = {
        yych = *YYCURSOR;
        switch (yych) {
        case 'C':
-       case 'O':       goto yy13;
+       case 'O':       goto yy4;
        case 'N':       goto yy5;
-       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 'R':       goto yy6;
+       case 'S':       goto yy7;
+       case 'a':       goto yy8;
+       case 'b':       goto yy9;
+       case 'd':       goto yy10;
+       case 'i':       goto yy11;
        case 'o':       goto yy12;
-       case 'r':       goto yy4;
-       case 's':       goto yy9;
-       case '}':       goto yy14;
-       default:        goto yy16;
+       case 'r':       goto yy13;
+       case 's':       goto yy14;
+       case '}':       goto yy15;
+       default:        goto yy2;
        }
  yy2:
-       yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy88;
+       ++YYCURSOR;
  yy3:
- #line 1054 "ext/standard/var_unserializer.re"
 -#line 990 "ext/standard/var_unserializer.re"
++#line 1043 "ext/standard/var_unserializer.re"
        { return 0; }
- #line 727 "ext/standard/var_unserializer.c"
 -#line 675 "ext/standard/var_unserializer.c"
++#line 716 "ext/standard/var_unserializer.c"
  yy4:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy83;
+       if (yych == ':') goto yy17;
        goto yy3;
  yy5:
        yych = *++YYCURSOR;
@@@ -762,88 -710,493 +751,441 @@@ yy12
        goto yy3;
  yy13:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy17;
+       if (yych == ':') goto yy28;
        goto yy3;
  yy14:
+       yych = *(YYMARKER = ++YYCURSOR);
+       if (yych == ':') goto yy29;
+       goto yy3;
+ yy15:
        ++YYCURSOR;
- #line 1048 "ext/standard/var_unserializer.re"
 -#line 984 "ext/standard/var_unserializer.re"
++#line 1037 "ext/standard/var_unserializer.re"
        {
        /* this is the case where we have less data than planned */
        php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
        return 0; /* not sure if it should be 0 or 1 here? */
  }
- #line 776 "ext/standard/var_unserializer.c"
- yy16:
-       yych = *++YYCURSOR;
-       goto yy3;
 -#line 728 "ext/standard/var_unserializer.c"
++#line 769 "ext/standard/var_unserializer.c"
  yy17:
        yych = *++YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy19;
 -              goto yy31;
++              goto yy30;
        }
 -      if (yych == '+') goto yy30;
  yy18:
        YYCURSOR = YYMARKER;
        goto yy3;
  yy19:
        ++YYCURSOR;
 -#line 668 "ext/standard/var_unserializer.re"
++#line 709 "ext/standard/var_unserializer.re"
+       {
+       *p = YYCURSOR;
+       ZVAL_NULL(rval);
+       return 1;
+ }
 -#line 746 "ext/standard/var_unserializer.c"
++#line 786 "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 (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy32;
++      goto yy18;
+ yy22:
+       yych = *++YYCURSOR;
 -      if (yych == '+') goto yy36;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy37;
++      if (yych <= '9') goto yy34;
+       goto yy18;
+ yy23:
+       yych = *++YYCURSOR;
 -      if (yych == '+') goto yy39;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy40;
++      if (yych <= '9') goto yy36;
+       goto yy18;
+ yy24:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '1') goto yy42;
++      if (yych <= '1') goto yy38;
+       goto yy18;
+ yy25:
+       yych = *++YYCURSOR;
+       if (yych <= '/') {
+               if (yych <= ',') {
 -                      if (yych == '+') goto yy43;
++                      if (yych == '+') goto yy39;
+                       goto yy18;
+               } else {
 -                      if (yych <= '-') goto yy44;
 -                      if (yych <= '.') goto yy45;
++                      if (yych <= '-') goto yy40;
++                      if (yych <= '.') goto yy41;
+                       goto yy18;
+               }
+       } else {
+               if (yych <= 'I') {
 -                      if (yych <= '9') goto yy46;
++                      if (yych <= '9') goto yy42;
+                       if (yych <= 'H') goto yy18;
 -                      goto yy48;
++                      goto yy44;
+               } else {
 -                      if (yych == 'N') goto yy49;
++                      if (yych == 'N') goto yy45;
+                       goto yy18;
+               }
+       }
+ yy26:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
 -              if (yych == '+') goto yy50;
++              if (yych == '+') goto yy46;
+               goto yy18;
+       } else {
 -              if (yych <= '-') goto yy50;
++              if (yych <= '-') goto yy46;
+               if (yych <= '/') goto yy18;
 -              if (yych <= '9') goto yy51;
++              if (yych <= '9') goto yy47;
+               goto yy18;
+       }
+ 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 (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy49;
++      goto yy18;
+ yy28:
+       yych = *++YYCURSOR;
 -      if (yych <= ',') {
 -              if (yych == '+') goto yy56;
 -              goto yy18;
 -      } else {
 -              if (yych <= '-') goto yy56;
 -              if (yych <= '/') goto yy18;
 -              if (yych <= '9') goto yy57;
 -              goto yy18;
 -      }
++      if (yych <= '/') goto yy18;
++      if (yych <= '9') goto yy51;
++      goto yy18;
+ yy29:
+       yych = *++YYCURSOR;
 -      if (yych == '+') goto yy59;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy60;
++      if (yych <= '9') goto yy53;
+       goto yy18;
+ yy30:
 -      yych = *++YYCURSOR;
 -      if (yybm[0+yych] & 128) {
 -              goto yy31;
 -      }
 -      goto yy18;
 -yy31:
+       ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy19;
 -              goto yy31;
++              goto yy30;
+       }
+       if (yych <= '/') goto yy18;
 -      if (yych <= ':') goto yy62;
++      if (yych <= ':') goto yy55;
+       goto yy18;
 -yy33:
 -      yych = *++YYCURSOR;
 -      if (yych <= '/') goto yy18;
 -      if (yych >= ':') goto yy18;
 -yy34:
++yy32:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy34;
 -      if (yych == ';') goto yy63;
++      if (yych <= '9') goto yy32;
++      if (yych == ';') goto yy56;
+       goto yy18;
 -yy36:
 -      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;
++      if (yych <= '9') goto yy34;
++      if (yych <= ':') goto yy58;
+       goto yy18;
 -yy39:
 -      yych = *++YYCURSOR;
 -      if (yych <= '/') goto yy18;
 -      if (yych >= ':') goto yy18;
 -yy40:
++yy36:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy40;
 -      if (yych <= ':') goto yy66;
++      if (yych <= '9') goto yy36;
++      if (yych <= ':') goto yy59;
+       goto yy18;
 -yy42:
++yy38:
+       yych = *++YYCURSOR;
 -      if (yych == ';') goto yy67;
++      if (yych == ';') goto yy60;
+       goto yy18;
 -yy43:
++yy39:
+       yych = *++YYCURSOR;
 -      if (yych == '.') goto yy45;
++      if (yych == '.') goto yy41;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy46;
++      if (yych <= '9') goto yy42;
+       goto yy18;
 -yy44:
++yy40:
+       yych = *++YYCURSOR;
+       if (yych <= '/') {
+               if (yych != '.') goto yy18;
+       } else {
 -              if (yych <= '9') goto yy46;
 -              if (yych == 'I') goto yy48;
++              if (yych <= '9') goto yy42;
++              if (yych == 'I') goto yy44;
+               goto yy18;
        }
 -yy45:
++yy41:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy69;
++      if (yych <= '9') goto yy62;
+       goto yy18;
 -yy46:
++yy42:
+       ++YYCURSOR;
 -      if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
++      if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       if (yych <= ':') {
+               if (yych <= '.') {
+                       if (yych <= '-') goto yy18;
 -                      goto yy69;
++                      goto yy62;
+               } else {
+                       if (yych <= '/') goto yy18;
 -                      if (yych <= '9') goto yy46;
++                      if (yych <= '9') goto yy42;
+                       goto yy18;
+               }
+       } else {
+               if (yych <= 'E') {
 -                      if (yych <= ';') goto yy71;
++                      if (yych <= ';') goto yy64;
+                       if (yych <= 'D') goto yy18;
 -                      goto yy73;
++                      goto yy66;
+               } else {
 -                      if (yych == 'e') goto yy73;
++                      if (yych == 'e') goto yy66;
+                       goto yy18;
+               }
+       }
 -yy48:
++yy44:
+       yych = *++YYCURSOR;
 -      if (yych == 'N') goto yy74;
++      if (yych == 'N') goto yy67;
+       goto yy18;
 -yy49:
++yy45:
+       yych = *++YYCURSOR;
 -      if (yych == 'A') goto yy75;
++      if (yych == 'A') goto yy68;
+       goto yy18;
 -yy50:
++yy46:
+       yych = *++YYCURSOR;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
 -yy51:
++yy47:
+       ++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 yy47;
++      if (yych == ';') goto yy69;
+       goto yy18;
 -yy53:
 -      yych = *++YYCURSOR;
 -      if (yych <= '/') goto yy18;
 -      if (yych >= ':') goto yy18;
 -yy54:
++yy49:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy54;
 -      if (yych <= ':') goto yy78;
++      if (yych <= '9') goto yy49;
++      if (yych <= ':') goto yy71;
+       goto yy18;
 -yy56:
 -      yych = *++YYCURSOR;
 -      if (yych <= '/') goto yy18;
 -      if (yych >= ':') goto yy18;
 -yy57:
++yy51:
+       ++YYCURSOR;
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
+       yych = *YYCURSOR;
+       if (yych <= '/') goto yy18;
 -      if (yych <= '9') goto yy57;
 -      if (yych == ';') goto yy79;
++      if (yych <= '9') goto yy51;
++      if (yych == ';') goto yy72;
+       goto yy18;
 -yy59:
 -      yych = *++YYCURSOR;
 -      if (yych <= '/') goto yy18;
 -      if (yych >= ':') goto yy18;
 -yy60:
++yy53:
+       ++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych >= ';') goto yy18;
 -      if (yych <= '9') goto yy60;
 -      if (yych <= ':') goto yy81;
++      if (yych <= '9') goto yy53;
++      if (yych <= ':') goto yy74;
+       goto yy18;
 -yy62:
++yy55:
        yych = *++YYCURSOR;
-       if (yych != '"') goto yy18;
 -      if (yych == '"') goto yy82;
++      if (yych == '"') goto yy75;
+       goto yy18;
 -yy63:
++yy56:
        ++YYCURSOR;
- #line 896 "ext/standard/var_unserializer.re"
 -#line 619 "ext/standard/var_unserializer.re"
++#line 660 "ext/standard/var_unserializer.re"
        {
-       size_t len, len2, len3, maxlen;
-       zend_long elements;
-       char *str;
-       zend_string *class_name;
-       zend_class_entry *ce;
-       int incomplete_class = 0;
-       int custom_object = 0;
+       zend_long id;
  
-       zval user_func;
-       zval retval;
-       zval args[1];
+       *p = YYCURSOR;
+       if (!var_hash) return 0;
  
-     if (!var_hash) return 0;
-       if (*start == 'C') {
-               custom_object = 1;
 -      id = parse_iv(start + 2) - 1;
++      id = parse_uiv(start + 2) - 1;
+       if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
+               return 0;
        }
  
-       len2 = len = parse_uiv(start + 2);
-       maxlen = max - YYCURSOR;
-       if (maxlen < len || len == 0) {
-               *p = start + 2;
+       if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
                return 0;
        }
  
-       str = (char*)YYCURSOR;
-       YYCURSOR += len;
+       if (Z_ISREF_P(rval_ref)) {
+               ZVAL_COPY(rval, rval_ref);
+       } else {
+               ZVAL_NEW_REF(rval_ref, rval_ref);
+               ZVAL_COPY(rval, rval_ref);
+       }
  
-       if (*(YYCURSOR) != '"') {
-               *p = YYCURSOR;
-               return 0;
+       return 1;
+ }
 -#line 1021 "ext/standard/var_unserializer.c"
 -yy65:
++#line 1010 "ext/standard/var_unserializer.c"
++yy58:
+       yych = *++YYCURSOR;
 -      if (yych == '"') goto yy84;
++      if (yych == '"') goto yy77;
+       goto yy18;
 -yy66:
++yy59:
+       yych = *++YYCURSOR;
 -      if (yych == '{') goto yy86;
++      if (yych == '{') goto yy79;
+       goto yy18;
 -yy67:
++yy60:
+       ++YYCURSOR;
 -#line 674 "ext/standard/var_unserializer.re"
++#line 715 "ext/standard/var_unserializer.re"
+       {
+       *p = YYCURSOR;
+       ZVAL_BOOL(rval, parse_iv(start + 2));
+       return 1;
+ }
 -#line 1038 "ext/standard/var_unserializer.c"
 -yy69:
++#line 1027 "ext/standard/var_unserializer.c"
++yy62:
+       ++YYCURSOR;
 -      if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
++      if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+       yych = *YYCURSOR;
+       if (yych <= ';') {
+               if (yych <= '/') goto yy18;
 -              if (yych <= '9') goto yy69;
++              if (yych <= '9') goto yy62;
+               if (yych <= ':') goto yy18;
+       } else {
+               if (yych <= 'E') {
+                       if (yych <= 'D') goto yy18;
 -                      goto yy73;
++                      goto yy66;
+               } else {
 -                      if (yych == 'e') goto yy73;
++                      if (yych == 'e') goto yy66;
+                       goto yy18;
+               }
        }
-       if (*(YYCURSOR+1) != ':') {
-               *p = YYCURSOR+1;
-               return 0;
 -yy71:
++yy64:
+       ++YYCURSOR;
 -#line 722 "ext/standard/var_unserializer.re"
++#line 763 "ext/standard/var_unserializer.re"
+       {
+ #if SIZEOF_ZEND_LONG == 4
+ use_double:
+ #endif
+       *p = YYCURSOR;
+       ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
+       return 1;
+ }
 -#line 1067 "ext/standard/var_unserializer.c"
 -yy73:
++#line 1056 "ext/standard/var_unserializer.c"
++yy66:
+       yych = *++YYCURSOR;
+       if (yych <= ',') {
 -              if (yych == '+') goto yy88;
++              if (yych == '+') goto yy81;
+               goto yy18;
+       } else {
 -              if (yych <= '-') goto yy88;
++              if (yych <= '-') goto yy81;
+               if (yych <= '/') goto yy18;
 -              if (yych <= '9') goto yy89;
++              if (yych <= '9') goto yy82;
+               goto yy18;
        }
-       len3 = strspn(str, "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)
 -yy74:
++yy67:
+       yych = *++YYCURSOR;
 -      if (yych == 'F') goto yy91;
++      if (yych == 'F') goto yy84;
+       goto yy18;
 -yy75:
++yy68:
+       yych = *++YYCURSOR;
 -      if (yych == 'N') goto yy91;
++      if (yych == 'N') goto yy84;
+       goto yy18;
 -yy76:
++yy69:
+       ++YYCURSOR;
 -#line 680 "ext/standard/var_unserializer.re"
++#line 721 "ext/standard/var_unserializer.re"
        {
-               *p = YYCURSOR + len3 - len;
-               return 0;
+ #if SIZEOF_ZEND_LONG == 4
+       int digits = YYCURSOR - start - 3;
+       if (start[2] == '-' || start[2] == '+') {
+               digits--;
        }
  
-       class_name = zend_string_init(str, len, 0);
+       /* Use double for large zend_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((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
+                       if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
+                               goto use_double;
+                       }
+               } else {
+                       goto use_double;
+               }
+       }
+ #endif
+       *p = YYCURSOR;
+       ZVAL_LONG(rval, parse_iv(start + 2));
+       return 1;
+ }
 -#line 1115 "ext/standard/var_unserializer.c"
 -yy78:
++#line 1104 "ext/standard/var_unserializer.c"
++yy71:
+       yych = *++YYCURSOR;
 -      if (yych == '"') goto yy92;
++      if (yych == '"') goto yy85;
+       goto yy18;
 -yy79:
++yy72:
+       ++YYCURSOR;
 -#line 644 "ext/standard/var_unserializer.re"
++#line 685 "ext/standard/var_unserializer.re"
+       {
+       zend_long id;
+       *p = YYCURSOR;
+       if (!var_hash) return 0;
 -      id = parse_iv(start + 2) - 1;
++      id = parse_uiv(start + 2) - 1;
+       if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
+               return 0;
+       }
+       if (rval_ref == rval) {
+               return 0;
+       }
+       if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
+               return 0;
+       }
+       ZVAL_COPY(rval, rval_ref);
+       return 1;
+ }
 -#line 1146 "ext/standard/var_unserializer.c"
 -yy81:
++#line 1135 "ext/standard/var_unserializer.c"
++yy74:
+       yych = *++YYCURSOR;
 -      if (yych == '"') goto yy94;
++      if (yych == '"') goto yy87;
+       goto yy18;
 -yy82:
++yy75:
+       ++YYCURSOR;
 -#line 832 "ext/standard/var_unserializer.re"
++#line 885 "ext/standard/var_unserializer.re"
+       {
+       size_t len, len2, len3, maxlen;
+       zend_long elements;
+       char *str;
+       zend_string *class_name;
+       zend_class_entry *ce;
+       int incomplete_class = 0;
+       int custom_object = 0;
+       zval user_func;
+       zval retval;
+       zval args[1];
+     if (!var_hash) return 0;
+       if (*start == 'C') {
+               custom_object = 1;
+       }
+       len2 = len = parse_uiv(start + 2);
+       maxlen = max - YYCURSOR;
+       if (maxlen < len || len == 0) {
+               *p = start + 2;
+               return 0;
+       }
+       str = (char*)YYCURSOR;
+       YYCURSOR += len;
+       if (*(YYCURSOR) != '"') {
+               *p = YYCURSOR;
+               return 0;
+       }
+       if (*(YYCURSOR+1) != ':') {
+               *p = YYCURSOR+1;
+               return 0;
+       }
+       len3 = strspn(str, "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 = zend_string_init(str, len, 0);
  
        do {
                if(!unserialize_allowed_class(class_name, var_hash)) {
  
        return object_common2(UNSERIALIZE_PASSTHRU, elements);
  }
- #line 952 "ext/standard/var_unserializer.c"
- yy24:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy25:
-       ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy25;
-       if (yych >= ';') goto yy18;
-       yych = *++YYCURSOR;
-       if (yych != '"') goto yy18;
 -#line 1305 "ext/standard/var_unserializer.c"
 -yy84:
++#line 1294 "ext/standard/var_unserializer.c"
++yy77:
        ++YYCURSOR;
- #line 885 "ext/standard/var_unserializer.re"
 -#line 763 "ext/standard/var_unserializer.re"
++#line 810 "ext/standard/var_unserializer.re"
        {
-       zend_long elements;
-     if (!var_hash) return 0;
+       size_t len, maxlen;
+       zend_string *str;
  
-       elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
-       if (elements < 0 || elements >= HT_MAX_SIZE) {
+       len = parse_uiv(start + 2);
+       maxlen = max - YYCURSOR;
+       if (maxlen < len) {
+               *p = start + 2;
                return 0;
        }
-       return object_common2(UNSERIALIZE_PASSTHRU, elements);
+       if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) {
+               return 0;
+       }
+       if (*(YYCURSOR) != '"') {
+               zend_string_free(str);
+               *p = YYCURSOR;
+               return 0;
+       }
+       if (*(YYCURSOR + 1) != ';') {
+               efree(str);
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+       YYCURSOR += 2;
+       *p = YYCURSOR;
+       ZVAL_STR(rval, str);
+       return 1;
  }
- #line 978 "ext/standard/var_unserializer.c"
- yy30:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy31:
-       ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy31;
-       if (yych >= ';') goto yy18;
-       yych = *++YYCURSOR;
-       if (yych != '{') goto yy18;
 -#line 1342 "ext/standard/var_unserializer.c"
 -yy86:
++#line 1331 "ext/standard/var_unserializer.c"
++yy79:
        ++YYCURSOR;
- #line 855 "ext/standard/var_unserializer.re"
 -#line 797 "ext/standard/var_unserializer.re"
++#line 844 "ext/standard/var_unserializer.re"
        {
        zend_long elements = parse_iv(start + 2);
        /* use iv() not uiv() in order to check data range */
  
        return finish_nested_data(UNSERIALIZE_PASSTHRU);
  }
- #line 1023 "ext/standard/var_unserializer.c"
- yy36:
 -#line 1369 "ext/standard/var_unserializer.c"
 -yy88:
++#line 1364 "ext/standard/var_unserializer.c"
++yy81:
        yych = *++YYCURSOR;
 -      if (yych <= ',') {
 -              if (yych == '+') goto yy96;
 -              goto yy18;
 -      } else {
 -              if (yych <= '-') goto yy96;
 -              if (yych <= '/') goto yy18;
 -              if (yych >= ':') goto yy18;
 -      }
 -yy89:
 +      if (yych <= '/') goto yy18;
 +      if (yych >= ':') goto yy18;
- yy37:
++yy82:
        ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy37;
-       if (yych >= ';') goto yy18;
 -      if (yych <= '9') goto yy89;
 -      if (yych == ';') goto yy71;
++      if (yych <= '9') goto yy82;
++      if (yych == ';') goto yy64;
+       goto yy18;
 -yy91:
++yy84:
        yych = *++YYCURSOR;
-       if (yych != '"') goto yy18;
 -      if (yych == ';') goto yy97;
++      if (yych == ';') goto yy89;
+       goto yy18;
 -yy92:
++yy85:
        ++YYCURSOR;
--#line 821 "ext/standard/var_unserializer.re"
++#line 874 "ext/standard/var_unserializer.re"
        {
-       size_t len, maxlen;
-       zend_string *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) != '"') {
-               zend_string_free(str);
-               *p = YYCURSOR;
-               return 0;
-       }
+       zend_long elements;
+     if (!var_hash) return 0;
  
-       if (*(YYCURSOR + 1) != ';') {
-               efree(str);
-               *p = YYCURSOR + 1;
+       elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
+       if (elements < 0 || elements >= HT_MAX_SIZE) {
                return 0;
        }
-       YYCURSOR += 2;
-       *p = YYCURSOR;
-       ZVAL_STR(rval, str);
-       return 1;
+       return object_common2(UNSERIALIZE_PASSTHRU, elements);
  }
- #line 1072 "ext/standard/var_unserializer.c"
- yy42:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy43:
 -#line 1405 "ext/standard/var_unserializer.c"
 -yy94:
++#line 1394 "ext/standard/var_unserializer.c"
++yy87:
        ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy43;
-       if (yych >= ';') goto yy18;
-       yych = *++YYCURSOR;
-       if (yych != '"') goto yy18;
-       ++YYCURSOR;
- #line 783 "ext/standard/var_unserializer.re"
 -#line 731 "ext/standard/var_unserializer.re"
++#line 772 "ext/standard/var_unserializer.re"
        {
        size_t len, maxlen;
        char *str;
        YYCURSOR += 2;
        *p = YYCURSOR;
  
 -      ZVAL_STRINGL(rval, str, len);
 +      if (len == 0) {
 +              ZVAL_EMPTY_STRING(rval);
 +      } else if (len == 1) {
 +              ZVAL_INTERNED_STR(rval, ZSTR_CHAR((zend_uchar)*str));
 +      } else {
 +              ZVAL_STRINGL(rval, str, len);
 +      }
        return 1;
  }
- #line 1125 "ext/standard/var_unserializer.c"
- yy48:
-       yych = *++YYCURSOR;
-       if (yych <= '/') {
-               if (yych <= ',') {
-                       if (yych == '+') goto yy52;
-                       goto yy18;
-               } else {
-                       if (yych <= '-') goto yy50;
-                       if (yych <= '.') goto yy55;
-                       goto yy18;
-               }
-       } else {
-               if (yych <= 'I') {
-                       if (yych <= '9') goto yy53;
-                       if (yych <= 'H') goto yy18;
-                       goto yy51;
-               } else {
-                       if (yych != 'N') goto yy18;
-               }
-       }
-       yych = *++YYCURSOR;
-       if (yych == 'A') goto yy70;
-       goto yy18;
- yy50:
-       yych = *++YYCURSOR;
-       if (yych <= '/') {
-               if (yych == '.') goto yy55;
-               goto yy18;
-       } else {
-               if (yych <= '9') goto yy53;
-               if (yych != 'I') goto yy18;
-       }
- yy51:
-       yych = *++YYCURSOR;
-       if (yych == 'N') goto yy66;
-       goto yy18;
- yy52:
-       yych = *++YYCURSOR;
-       if (yych == '.') goto yy55;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy53:
-       ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
-       yych = *YYCURSOR;
-       if (yych <= ':') {
-               if (yych <= '.') {
-                       if (yych <= '-') goto yy18;
-                       goto yy64;
-               } else {
-                       if (yych <= '/') goto yy18;
-                       if (yych <= '9') goto yy53;
-                       goto yy18;
-               }
-       } else {
-               if (yych <= 'E') {
-                       if (yych <= ';') goto yy58;
-                       if (yych <= 'D') goto yy18;
-                       goto yy60;
-               } else {
-                       if (yych == 'e') goto yy60;
-                       goto yy18;
-               }
-       }
- yy55:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy56:
-       ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
-       yych = *YYCURSOR;
-       if (yych <= ';') {
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy56;
-               if (yych <= ':') goto yy18;
-       } else {
-               if (yych <= 'E') {
-                       if (yych <= 'D') goto yy18;
-                       goto yy60;
-               } else {
-                       if (yych == 'e') goto yy60;
-                       goto yy18;
-               }
-       }
- yy58:
-       ++YYCURSOR;
- #line 774 "ext/standard/var_unserializer.re"
-       {
- #if SIZEOF_ZEND_LONG == 4
- use_double:
- #endif
-       *p = YYCURSOR;
-       ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
-       return 1;
- }
- #line 1222 "ext/standard/var_unserializer.c"
- yy60:
-       yych = *++YYCURSOR;
-       if (yych <= ',') {
-               if (yych != '+') goto yy18;
-       } else {
-               if (yych <= '-') goto yy61;
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy62;
-               goto yy18;
-       }
- yy61:
 -#line 1440 "ext/standard/var_unserializer.c"
 -yy96:
--      yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy62:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
--      if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy62;
-       if (yych == ';') goto yy58;
 -      if (yych <= '9') goto yy89;
--      goto yy18;
- yy64:
-       ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
-       yych = *YYCURSOR;
-       if (yych <= ';') {
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy64;
-               if (yych <= ':') goto yy18;
-               goto yy58;
-       } else {
-               if (yych <= 'E') {
-                       if (yych <= 'D') goto yy18;
-                       goto yy60;
-               } else {
-                       if (yych == 'e') goto yy60;
-                       goto yy18;
-               }
-       }
- yy66:
-       yych = *++YYCURSOR;
-       if (yych != 'F') goto yy18;
- yy67:
-       yych = *++YYCURSOR;
-       if (yych != ';') goto yy18;
 -yy97:
++#line 1435 "ext/standard/var_unserializer.c"
++yy89:
        ++YYCURSOR;
- #line 758 "ext/standard/var_unserializer.re"
 -#line 706 "ext/standard/var_unserializer.re"
++#line 747 "ext/standard/var_unserializer.re"
        {
        *p = YYCURSOR;
  
  
        return 1;
  }
- #line 1286 "ext/standard/var_unserializer.c"
- yy70:
-       yych = *++YYCURSOR;
-       if (yych == 'N') goto yy67;
-       goto yy18;
- yy71:
-       yych = *++YYCURSOR;
-       if (yych <= ',') {
-               if (yych != '+') goto yy18;
-       } else {
-               if (yych <= '-') goto yy72;
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy73;
-               goto yy18;
-       }
- yy72:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy73:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy73;
-       if (yych != ';') goto yy18;
-       ++YYCURSOR;
- #line 732 "ext/standard/var_unserializer.re"
-       {
- #if SIZEOF_ZEND_LONG == 4
-       int digits = YYCURSOR - start - 3;
-       if (start[2] == '-' || start[2] == '+') {
-               digits--;
-       }
-       /* Use double for large zend_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((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
-                       if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
-                               goto use_double;
-                       }
-               } else {
-                       goto use_double;
-               }
-       }
- #endif
-       *p = YYCURSOR;
-       ZVAL_LONG(rval, parse_iv(start + 2));
-       return 1;
- }
- #line 1339 "ext/standard/var_unserializer.c"
- yy77:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= '2') goto yy18;
-       yych = *++YYCURSOR;
-       if (yych != ';') goto yy18;
-       ++YYCURSOR;
- #line 726 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-       ZVAL_BOOL(rval, parse_iv(start + 2));
-       return 1;
- }
- #line 1353 "ext/standard/var_unserializer.c"
- yy81:
-       ++YYCURSOR;
- #line 720 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-       ZVAL_NULL(rval);
-       return 1;
- }
- #line 1362 "ext/standard/var_unserializer.c"
- yy83:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy84:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy84;
-       if (yych != ';') goto yy18;
-       ++YYCURSOR;
- #line 695 "ext/standard/var_unserializer.re"
-       {
-       zend_long id;
-       *p = YYCURSOR;
-       if (!var_hash) return 0;
-       id = parse_uiv(start + 2) - 1;
-       if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
-               return 0;
-       }
-       if (rval_ref == rval) {
-               return 0;
-       }
-       if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
-               ZVAL_UNDEF(rval);
-               return 1;
-       }
-       ZVAL_COPY(rval, rval_ref);
-       return 1;
- }
- #line 1400 "ext/standard/var_unserializer.c"
- yy88:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych >= ':') goto yy18;
- yy89:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy89;
-       if (yych != ';') goto yy18;
-       ++YYCURSOR;
- #line 669 "ext/standard/var_unserializer.re"
-       {
-       zend_long id;
-       *p = YYCURSOR;
-       if (!var_hash) return 0;
-       id = parse_uiv(start + 2) - 1;
-       if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
-               return 0;
-       }
-       zval_ptr_dtor(rval);
-       if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
-               ZVAL_UNDEF(rval);
-               return 1;
-       }
-       if (Z_ISREF_P(rval_ref)) {
-               ZVAL_COPY(rval, rval_ref);
-       } else {
-               ZVAL_NEW_REF(rval_ref, rval_ref);
-               ZVAL_COPY(rval, rval_ref);
-       }
-       return 1;
- }
- #line 1439 "ext/standard/var_unserializer.c"
 -#line 1464 "ext/standard/var_unserializer.c"
++#line 1454 "ext/standard/var_unserializer.c"
  }
- #line 1056 "ext/standard/var_unserializer.re"
 -#line 992 "ext/standard/var_unserializer.re"
++#line 1045 "ext/standard/var_unserializer.re"
  
  
        return 0;
index 1285d41b471e3e46b4e7e6d8406377de90251b8e,d9069af660edf48ead64c7e2c9940d6e947c4cb4..de0db395e393819aa65dd52dd9c5cfd2b4bf5b0c
@@@ -495,17 -454,8 +495,8 @@@ string_key
                        return 0;
                }
  
-               if (UNEXPECTED(Z_ISUNDEF_P(data))) {
-                       if (Z_TYPE(key) == IS_LONG) {
-                               zend_hash_index_del(ht, Z_LVAL(key));
-                       } else {
-                               zend_hash_del_ind(ht, Z_STR(key));
-                       }
-               } else {
-                       var_push_dtor(var_hash, data);
-               }
+               var_push_dtor(var_hash, data);
 -              zval_dtor(&key);
 +              zval_ptr_dtor(&key);
  
                if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
                        (*p)--;