]> granicus.if.org Git - php/commitdiff
Use interned empty and "one char" strings.
authorDmitry Stogov <dmitry@zend.com>
Thu, 18 May 2017 14:59:59 +0000 (17:59 +0300)
committerDmitry Stogov <dmitry@zend.com>
Thu, 18 May 2017 14:59:59 +0000 (17:59 +0300)
Zend/zend_operators.c
ext/mysqlnd/mysqlnd_wireprotocol.c
ext/standard/array.c
ext/standard/basic_functions.c
ext/standard/string.c
ext/standard/var_unserializer.c
ext/standard/var_unserializer.re
main/php_variables.c

index 41d1ca62e1eaf215914e8c8bac67e287b4aca31e..ea9e506dd61d0ce6f5fac2ebaf6b743e9c9e9cf3 100644 (file)
@@ -537,7 +537,7 @@ try_again:
                        break;
                }
                case IS_LONG: {
-                       ZVAL_NEW_STR(op, zend_long_to_str(Z_LVAL_P(op)));
+                       ZVAL_STR(op, zend_long_to_str(Z_LVAL_P(op)));
                        break;
                }
                case IS_DOUBLE: {
@@ -2856,9 +2856,13 @@ ZEND_API void ZEND_FASTCALL zend_locale_sprintf_double(zval *op ZEND_FILE_LINE_D
 
 ZEND_API zend_string* ZEND_FASTCALL zend_long_to_str(zend_long num) /* {{{ */
 {
-       char buf[MAX_LENGTH_OF_LONG + 1];
-       char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
-       return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
+       if ((zend_ulong)num <= 9) {
+               return ZSTR_CHAR((zend_uchar)'0' + (zend_uchar)num);
+       } else {
+               char buf[MAX_LENGTH_OF_LONG + 1];
+               char *res = zend_print_long_to_buf(buf + sizeof(buf) - 1, num);
+               return zend_string_init(res, buf + sizeof(buf) - 1 - res, 0);
+       }
 }
 /* }}} */
 
index 90ae615a1a72eb7cd3de7f0ec59aeb45298fc6d5..2a2cd9b977d915ba06820ee3f7df34987e097f48 100644 (file)
@@ -1766,6 +1766,10 @@ php_mysqlnd_rowp_read_text_protocol_aux(MYSQLND_MEMORY_POOL_CHUNK * row_buffer,
                                } else if (Z_TYPE_P(current_field) == IS_STRING) {
                                        /* nothing to do here, as we want a string and ps_fetch_from_1_to_8_bytes() has given us one */
                                }
+                       } else if (len == 0) {
+                               ZVAL_EMPTY_STRING(current_field);
+                       } else if (len == 1) {
+                               ZVAL_INTERNED_STR(current_field, ZSTR_CHAR((zend_uchar)*(char *)p));
                        } else {
                                ZVAL_STRINGL(current_field, (char *)p, len);
                        }
index 69c98d8b7a59198073ea4ef8122cb2671d498c27..2744ee33069ab0ba0f5797d3472155548aabf4be 100644 (file)
@@ -3807,19 +3807,19 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE
                Z_PARAM_VARIADIC('+', args, argc)
        ZEND_PARSE_PARAMETERS_END();
 
-       for (i = 0; i < argc; i++) {
-               zval *arg = args + i;
-
-               if (Z_TYPE_P(arg) != IS_ARRAY) {
-                       php_error_docref(NULL, E_WARNING, "Argument #%d is not an array", i + 1);
-                       RETURN_NULL();
-               }
-       }
-
 
        if (replace) {
                HashTable *dest;
 
+               for (i = 0; i < argc; i++) {
+                       zval *arg = args + i;
+
+                       if (Z_TYPE_P(arg) != IS_ARRAY) {
+                               php_error_docref(NULL, E_WARNING, "Argument #%d is not an array", i + 1);
+                               RETURN_NULL();
+                       }
+               }
+
                /* copy first array */
                arg = args;
                dest = zend_array_dup(Z_ARRVAL_P(arg));
@@ -3838,11 +3838,22 @@ static inline void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETE
        } else {
                zval *src_entry;
                HashTable *src, *dest;
+               uint32_t count = 0;
+
+               for (i = 0; i < argc; i++) {
+                       zval *arg = args + i;
+
+                       if (Z_TYPE_P(arg) != IS_ARRAY) {
+                               php_error_docref(NULL, E_WARNING, "Argument #%d is not an array", i + 1);
+                               RETURN_NULL();
+                       }
+                       count += zend_hash_num_elements(Z_ARRVAL_P(arg));
+               }
 
                arg = args;
                src  = Z_ARRVAL_P(arg);
                /* copy first array */
-               array_init_size(return_value, zend_hash_num_elements(src));
+               array_init_size(return_value, count);
                dest = Z_ARRVAL_P(return_value);
                if (src->u.flags & HASH_FLAG_PACKED) {
                        zend_hash_real_init(dest, 1);
index 56131e72ea4df9ef742175481e8f4d78391e8302..3d911cec47c6d4d40fca77d2c75450b4601b9ec8 100644 (file)
@@ -5320,7 +5320,7 @@ PHP_FUNCTION(highlight_string)
 PHP_FUNCTION(ini_get)
 {
        char *varname, *str;
-       size_t varname_len;
+       size_t varname_len, len;
 
        ZEND_PARSE_PARAMETERS_START(1, 1)
                Z_PARAM_STRING(varname, varname_len)
@@ -5332,7 +5332,13 @@ PHP_FUNCTION(ini_get)
                RETURN_FALSE;
        }
 
-       RETURN_STRING(str);
+       len = strlen(str);
+       if (len == 0) {
+               RETURN_EMPTY_STRING();
+       } else if (len == 1) {
+               RETURN_INTERNED_STR(ZSTR_CHAR((zend_uchar)str[0]));
+       }
+       RETURN_STRINGL(str, len);
 }
 /* }}} */
 
@@ -5443,7 +5449,15 @@ PHP_FUNCTION(ini_set)
 
        /* copy to return here, because alter might free it! */
        if (old_value) {
-               RETVAL_STRING(old_value);
+               size_t len = strlen(old_value);
+
+               if (len == 0) {
+                       RETVAL_EMPTY_STRING();
+               } else if (len == 1) {
+                       RETVAL_INTERNED_STR(ZSTR_CHAR((zend_uchar)old_value[0]));
+               } else {
+                       RETVAL_STRINGL(old_value, len);
+               }
        } else {
                RETVAL_FALSE;
        }
index 4ae3546d512b28ffe85ffa2301cc275e11c90d81..83f59015ce2d6dbf2022a5faa07ee4e92a597159 100644 (file)
@@ -1094,7 +1094,15 @@ PHPAPI void php_explode(const zend_string *delim, zend_string *str, zval *return
                zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
        } else {
                do {
-                       ZVAL_STRINGL(&tmp, p1, p2 - p1);
+                       size_t l = p2 - p1;
+
+                       if (l == 0) {
+                               ZVAL_EMPTY_STRING(&tmp);
+                       } else if (l == 1) {
+                               ZVAL_INTERNED_STR(&tmp, ZSTR_CHAR((zend_uchar)(*p1)));
+                       } else {
+                               ZVAL_STRINGL(&tmp, p1, p2 - p1);
+                       }
                        zend_hash_next_index_insert_new(Z_ARRVAL_P(return_value), &tmp);
                        p1 = p2 + ZSTR_LEN(delim);
                        p2 = (char *) php_memnstr(p1, ZSTR_VAL(delim), ZSTR_LEN(delim), endp);
@@ -2420,6 +2428,14 @@ PHP_FUNCTION(substr)
                l = ZSTR_LEN(str) - f;
        }
 
+       if (l == 0) {
+               RETURN_EMPTY_STRING();
+       } else if (l == 1) {
+               RETURN_INTERNED_STR(ZSTR_CHAR((zend_uchar)(ZSTR_VAL(str)[f])));
+       } else if (l == ZSTR_LEN(str)) {
+               RETURN_STR_COPY(str);
+       }
+
        RETURN_STRINGL(ZSTR_VAL(str) + f, l);
 }
 /* }}} */
@@ -3227,7 +3243,14 @@ static zend_string *php_str_to_str_ex(zend_string *haystack,
 nothing_todo:
                return zend_string_copy(haystack);
        } else {
-               new_str = zend_string_init(str, str_len, 0);
+               if (str_len == 0) {
+                       new_str = ZSTR_EMPTY_ALLOC();
+               } else if (str_len == 1) {
+                       new_str = ZSTR_CHAR((zend_uchar)(*str));
+               } else {
+                       new_str = zend_string_init(str, str_len, 0);
+               }
+
                (*replace_count)++;
                return new_str;
        }
index a1f505c6f2b81db5932f74ea0faf30af7fef3413..612c34aaebfaa62c174a903597e7d55e0d413a62 100644 (file)
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.16 */
+/* Generated by re2c 0.14.3 */
 #line 1 "ext/standard/var_unserializer.re"
 /*
   +----------------------------------------------------------------------+
@@ -651,360 +651,516 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
                  0,   0,   0,   0,   0,   0,   0,   0, 
                  0,   0,   0,   0,   0,   0,   0,   0, 
        };
+
        if ((YYLIMIT - YYCURSOR) < 7) YYFILL(7);
        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 yy88;
 yy3:
-#line 1001 "ext/standard/var_unserializer.re"
+#line 1007 "ext/standard/var_unserializer.re"
        { return 0; }
-#line 678 "ext/standard/var_unserializer.c"
+#line 680 "ext/standard/var_unserializer.c"
 yy4:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy17;
+       if (yych == ':') goto yy83;
        goto yy3;
 yy5:
        yych = *++YYCURSOR;
-       if (yych == ';') goto yy19;
+       if (yych == ';') goto yy81;
        goto yy3;
 yy6:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy21;
+       if (yych == ':') goto yy77;
        goto yy3;
 yy7:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy22;
+       if (yych == ':') goto yy71;
        goto yy3;
 yy8:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy23;
+       if (yych == ':') goto yy48;
        goto yy3;
 yy9:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy24;
+       if (yych == ':') goto yy42;
        goto yy3;
 yy10:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy25;
+       if (yych == ':') goto yy36;
        goto yy3;
 yy11:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy26;
+       if (yych == ':') goto yy30;
        goto yy3;
 yy12:
        yych = *(YYMARKER = ++YYCURSOR);
-       if (yych == ':') goto yy27;
+       if (yych == ':') goto yy24;
        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 995 "ext/standard/var_unserializer.re"
+#line 1001 "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 731 "ext/standard/var_unserializer.c"
+#line 729 "ext/standard/var_unserializer.c"
+yy16:
+       yych = *++YYCURSOR;
+       goto yy3;
 yy17:
        yych = *++YYCURSOR;
        if (yybm[0+yych] & 128) {
-               goto yy30;
+               goto yy19;
        }
 yy18:
        YYCURSOR = YYMARKER;
        goto yy3;
 yy19:
        ++YYCURSOR;
-#line 673 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-       ZVAL_NULL(rval);
-       return 1;
-}
-#line 748 "ext/standard/var_unserializer.c"
-yy21:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy32;
-       goto yy18;
-yy22:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy34;
-       goto yy18;
-yy23:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy36;
-       goto yy18;
-yy24:
-       yych = *++YYCURSOR;
+       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+       yych = *YYCURSOR;
+       if (yybm[0+yych] & 128) {
+               goto yy19;
+       }
        if (yych <= '/') goto yy18;
-       if (yych <= '1') goto yy38;
-       goto yy18;
-yy25:
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych <= '/') {
-               if (yych <= ',') {
-                       if (yych == '+') goto yy39;
-                       goto yy18;
-               } else {
-                       if (yych <= '-') goto yy40;
-                       if (yych <= '.') goto yy41;
-                       goto yy18;
+       if (yych != '"') goto yy18;
+       ++YYCURSOR;
+#line 849 "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)) {
+                       incomplete_class = 1;
+                       ce = PHP_IC_ENTRY;
+                       break;
                }
-       } else {
-               if (yych <= 'I') {
-                       if (yych <= '9') goto yy42;
-                       if (yych <= 'H') goto yy18;
-                       goto yy44;
-               } else {
-                       if (yych == 'N') goto yy45;
-                       goto yy18;
+
+               /* Try to find class directly */
+               BG(serialize_lock)++;
+               ce = zend_lookup_class(class_name);
+               if (ce) {
+                       BG(serialize_lock)--;
+                       if (EG(exception)) {
+                               zend_string_release(class_name);
+                               return 0;
+                       }
+                       break;
+               }
+               BG(serialize_lock)--;
+
+               if (EG(exception)) {
+                       zend_string_release(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 */
+               ZVAL_STRING(&user_func, PG(unserialize_callback_func));
+
+               ZVAL_STR_COPY(&args[0], class_name);
+               BG(serialize_lock)++;
+               if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) {
+                       BG(serialize_lock)--;
+                       if (EG(exception)) {
+                               zend_string_release(class_name);
+                               zval_ptr_dtor(&user_func);
+                               zval_ptr_dtor(&args[0]);
+                               return 0;
+                       }
+                       php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func));
+                       incomplete_class = 1;
+                       ce = PHP_IC_ENTRY;
+                       zval_ptr_dtor(&user_func);
+                       zval_ptr_dtor(&args[0]);
+                       break;
+               }
+               BG(serialize_lock)--;
+               zval_ptr_dtor(&retval);
+               if (EG(exception)) {
+                       zend_string_release(class_name);
+                       zval_ptr_dtor(&user_func);
+                       zval_ptr_dtor(&args[0]);
+                       return 0;
+               }
+
+               /* The callback function may have defined the class */
+               BG(serialize_lock)++;
+               if ((ce = zend_lookup_class(class_name)) == NULL) {
+                       php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func));
+                       incomplete_class = 1;
+                       ce = PHP_IC_ENTRY;
+               }
+               BG(serialize_lock)--;
+
+               zval_ptr_dtor(&user_func);
+               zval_ptr_dtor(&args[0]);
+               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, ZSTR_VAL(class_name), len2);
                }
+               zend_string_release(class_name);
+               return ret;
        }
-yy26:
-       yych = *++YYCURSOR;
-       if (yych <= ',') {
-               if (yych == '+') goto yy46;
-               goto yy18;
-       } else {
-               if (yych <= '-') goto yy46;
-               if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy47;
-               goto yy18;
+
+       elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
+
+       if (elements < 0) {
+          zend_string_release(class_name);
+          return 0;
        }
-yy27:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy49;
-       goto yy18;
-yy28:
-       yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy51;
-       goto yy18;
-yy29:
+
+       if (incomplete_class) {
+               php_store_class_name(rval, ZSTR_VAL(class_name), len2);
+       }
+       zend_string_release(class_name);
+
+       return object_common2(UNSERIALIZE_PASSTHRU, elements);
+}
+#line 905 "ext/standard/var_unserializer.c"
+yy24:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy53;
-       goto yy18;
-yy30:
+       if (yych >= ':') goto yy18;
+yy25:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
-       if (yybm[0+yych] & 128) {
-               goto yy30;
-       }
-       if (yych <= '/') goto yy18;
-       if (yych <= ':') goto yy55;
-       goto yy18;
-yy32:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy32;
-       if (yych == ';') goto yy56;
-       goto yy18;
-yy34:
+       if (yych <= '9') goto yy25;
+       if (yych >= ';') goto yy18;
+       yych = *++YYCURSOR;
+       if (yych != '"') goto yy18;
        ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
-       yych = *YYCURSOR;
+#line 838 "ext/standard/var_unserializer.re"
+       {
+       long elements;
+    if (!var_hash) return 0;
+
+       elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
+       if (elements < 0) {
+               return 0;
+       }
+       return object_common2(UNSERIALIZE_PASSTHRU, elements);
+}
+#line 931 "ext/standard/var_unserializer.c"
+yy30:
+       yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy34;
-       if (yych <= ':') goto yy58;
-       goto yy18;
-yy36:
+       if (yych >= ':') goto yy18;
+yy31:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy36;
-       if (yych <= ':') goto yy59;
-       goto yy18;
-yy38:
-       yych = *++YYCURSOR;
-       if (yych == ';') goto yy60;
-       goto yy18;
-yy39:
-       yych = *++YYCURSOR;
-       if (yych == '.') goto yy41;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy42;
-       goto yy18;
-yy40:
-       yych = *++YYCURSOR;
-       if (yych <= '/') {
-               if (yych != '.') goto yy18;
-       } else {
-               if (yych <= '9') goto yy42;
-               if (yych == 'I') goto yy44;
-               goto yy18;
-       }
-yy41:
+       if (yych <= '9') goto yy31;
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy62;
-       goto yy18;
-yy42:
+       if (yych != '{') goto yy18;
        ++YYCURSOR;
-       if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
-       yych = *YYCURSOR;
-       if (yych <= ':') {
-               if (yych <= '.') {
-                       if (yych <= '-') goto yy18;
-                       goto yy62;
-               } else {
-                       if (yych <= '/') goto yy18;
-                       if (yych <= '9') goto yy42;
-                       goto yy18;
-               }
-       } else {
-               if (yych <= 'E') {
-                       if (yych <= ';') goto yy64;
-                       if (yych <= 'D') goto yy18;
-                       goto yy66;
-               } else {
-                       if (yych == 'e') goto yy66;
-                       goto yy18;
-               }
+#line 808 "ext/standard/var_unserializer.re"
+       {
+       zend_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;
        }
-yy44:
-       yych = *++YYCURSOR;
-       if (yych == 'N') goto yy67;
-       goto yy18;
-yy45:
-       yych = *++YYCURSOR;
-       if (yych == 'A') goto yy68;
-       goto yy18;
-yy46:
+
+       array_init_size(rval, elements);
+       if (elements) {
+               /* we can't convert from packed to hash during unserialization, because
+                  reference to some zvals might be keept in var_hash (to support references) */
+               zend_hash_real_init(Z_ARRVAL_P(rval), 0);
+       }
+
+       /* The array may contain references to itself, in which case we'll be modifying an
+        * rc>1 array. This is okay, since the array is, ostensibly, only visible to
+        * unserialize (in practice unserialization handlers also see it). Ideally we should
+        * prohibit "r:" references to non-objects, as we only generate them for objects. */
+       HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(rval));
+
+       if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) {
+               return 0;
+       }
+
+       return finish_nested_data(UNSERIALIZE_PASSTHRU);
+}
+#line 976 "ext/standard/var_unserializer.c"
+yy36:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
        if (yych >= ':') goto yy18;
-yy47:
-       ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
-       if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy47;
-       if (yych == ';') goto yy69;
-       goto yy18;
-yy49:
+yy37:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy49;
-       if (yych <= ':') goto yy71;
-       goto yy18;
-yy51:
+       if (yych <= '9') goto yy37;
+       if (yych >= ';') goto yy18;
+       yych = *++YYCURSOR;
+       if (yych != '"') goto yy18;
        ++YYCURSOR;
-       if (YYLIMIT <= YYCURSOR) YYFILL(1);
-       yych = *YYCURSOR;
+#line 774 "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;
+       }
+
+       if (*(YYCURSOR + 1) != ';') {
+               efree(str);
+               *p = YYCURSOR + 1;
+               return 0;
+       }
+
+       YYCURSOR += 2;
+       *p = YYCURSOR;
+
+       ZVAL_STR(rval, str);
+       return 1;
+}
+#line 1025 "ext/standard/var_unserializer.c"
+yy42:
+       yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy51;
-       if (yych == ';') goto yy72;
-       goto yy18;
-yy53:
+       if (yych >= ':') goto yy18;
+yy43:
        ++YYCURSOR;
        if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy53;
-       if (yych <= ':') goto yy74;
-       goto yy18;
-yy55:
+       if (yych <= '9') goto yy43;
+       if (yych >= ';') goto yy18;
        yych = *++YYCURSOR;
-       if (yych == '"') goto yy75;
-       goto yy18;
-yy56:
+       if (yych != '"') goto yy18;
        ++YYCURSOR;
-#line 622 "ext/standard/var_unserializer.re"
+#line 736 "ext/standard/var_unserializer.re"
        {
-       zend_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_uiv(start + 2) - 1;
-       if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
+       str = (char*)YYCURSOR;
+
+       YYCURSOR += len;
+
+       if (*(YYCURSOR) != '"') {
+               *p = YYCURSOR;
                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 (*(YYCURSOR + 1) != ';') {
+               *p = YYCURSOR + 1;
+               return 0;
        }
-       if (Z_ISREF_P(rval_ref)) {
-               ZVAL_COPY(rval, rval_ref);
+
+       YYCURSOR += 2;
+       *p = YYCURSOR;
+
+       if (len == 0) {
+               ZVAL_EMPTY_STRING(rval);
+       } else if (len == 1) {
+               ZVAL_INTERNED_STR(rval, ZSTR_CHAR((zend_uchar)*str));
        } else {
-               ZVAL_NEW_REF(rval_ref, rval_ref);
-               ZVAL_COPY(rval, rval_ref);
+               ZVAL_STRINGL(rval, str, len);
        }
-
        return 1;
 }
-#line 973 "ext/standard/var_unserializer.c"
-yy58:
+#line 1078 "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 == '"') goto yy77;
+       if (yych == 'A') goto yy70;
        goto yy18;
-yy59:
+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 == '{') goto yy79;
+       if (yych == 'N') goto yy66;
        goto yy18;
-yy60:
+yy52:
+       yych = *++YYCURSOR;
+       if (yych == '.') goto yy55;
+       if (yych <= '/') goto yy18;
+       if (yych >= ':') goto yy18;
+yy53:
        ++YYCURSOR;
-#line 679 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-       ZVAL_BOOL(rval, parse_iv(start + 2));
-       return 1;
-}
-#line 990 "ext/standard/var_unserializer.c"
-yy62:
+       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 yy62;
+               if (yych <= '9') goto yy56;
                if (yych <= ':') goto yy18;
        } else {
                if (yych <= 'E') {
                        if (yych <= 'D') goto yy18;
-                       goto yy66;
+                       goto yy60;
                } else {
-                       if (yych == 'e') goto yy66;
+                       if (yych == 'e') goto yy60;
                        goto yy18;
                }
        }
-yy64:
+yy58:
        ++YYCURSOR;
 #line 727 "ext/standard/var_unserializer.re"
        {
@@ -1015,27 +1171,96 @@ use_double:
        ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
        return 1;
 }
-#line 1019 "ext/standard/var_unserializer.c"
-yy66:
+#line 1175 "ext/standard/var_unserializer.c"
+yy60:
        yych = *++YYCURSOR;
        if (yych <= ',') {
-               if (yych == '+') goto yy81;
-               goto yy18;
+               if (yych != '+') goto yy18;
        } else {
-               if (yych <= '-') goto yy81;
+               if (yych <= '-') goto yy61;
                if (yych <= '/') goto yy18;
-               if (yych <= '9') goto yy82;
+               if (yych <= '9') goto yy62;
                goto yy18;
        }
-yy67:
+yy61:
        yych = *++YYCURSOR;
-       if (yych == 'F') goto yy84;
+       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;
        goto yy18;
-yy68:
+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;
+       ++YYCURSOR;
+#line 711 "ext/standard/var_unserializer.re"
+       {
+       *p = YYCURSOR;
+
+       if (!strncmp((char*)start + 2, "NAN", 3)) {
+               ZVAL_DOUBLE(rval, ZEND_NAN);
+       } else if (!strncmp((char*)start + 2, "INF", 3)) {
+               ZVAL_DOUBLE(rval, ZEND_INFINITY);
+       } else if (!strncmp((char*)start + 2, "-INF", 4)) {
+               ZVAL_DOUBLE(rval, -ZEND_INFINITY);
+       } else {
+               ZVAL_NULL(rval);
+       }
+
+       return 1;
+}
+#line 1239 "ext/standard/var_unserializer.c"
+yy70:
        yych = *++YYCURSOR;
-       if (yych == 'N') goto yy84;
+       if (yych == 'N') goto yy67;
        goto yy18;
-yy69:
+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 685 "ext/standard/var_unserializer.re"
        {
@@ -1063,12 +1288,41 @@ yy69:
        ZVAL_LONG(rval, parse_iv(start + 2));
        return 1;
 }
-#line 1067 "ext/standard/var_unserializer.c"
-yy71:
+#line 1292 "ext/standard/var_unserializer.c"
+yy77:
        yych = *++YYCURSOR;
-       if (yych == '"') goto yy85;
-       goto yy18;
-yy72:
+       if (yych <= '/') goto yy18;
+       if (yych >= '2') goto yy18;
+       yych = *++YYCURSOR;
+       if (yych != ';') goto yy18;
+       ++YYCURSOR;
+#line 679 "ext/standard/var_unserializer.re"
+       {
+       *p = YYCURSOR;
+       ZVAL_BOOL(rval, parse_iv(start + 2));
+       return 1;
+}
+#line 1306 "ext/standard/var_unserializer.c"
+yy81:
+       ++YYCURSOR;
+#line 673 "ext/standard/var_unserializer.re"
+       {
+       *p = YYCURSOR;
+       ZVAL_NULL(rval);
+       return 1;
+}
+#line 1315 "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 648 "ext/standard/var_unserializer.re"
        {
@@ -1095,322 +1349,48 @@ yy72:
 
        return 1;
 }
-#line 1099 "ext/standard/var_unserializer.c"
-yy74:
-       yych = *++YYCURSOR;
-       if (yych == '"') goto yy87;
-       goto yy18;
-yy75:
-       ++YYCURSOR;
-#line 843 "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)) {
-                       incomplete_class = 1;
-                       ce = PHP_IC_ENTRY;
-                       break;
-               }
-
-               /* Try to find class directly */
-               BG(serialize_lock)++;
-               ce = zend_lookup_class(class_name);
-               if (ce) {
-                       BG(serialize_lock)--;
-                       if (EG(exception)) {
-                               zend_string_release(class_name);
-                               return 0;
-                       }
-                       break;
-               }
-               BG(serialize_lock)--;
-
-               if (EG(exception)) {
-                       zend_string_release(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 */
-               ZVAL_STRING(&user_func, PG(unserialize_callback_func));
-
-               ZVAL_STR_COPY(&args[0], class_name);
-               BG(serialize_lock)++;
-               if (call_user_function_ex(CG(function_table), NULL, &user_func, &retval, 1, args, 0, NULL) != SUCCESS) {
-                       BG(serialize_lock)--;
-                       if (EG(exception)) {
-                               zend_string_release(class_name);
-                               zval_ptr_dtor(&user_func);
-                               zval_ptr_dtor(&args[0]);
-                               return 0;
-                       }
-                       php_error_docref(NULL, E_WARNING, "defined (%s) but not found", Z_STRVAL(user_func));
-                       incomplete_class = 1;
-                       ce = PHP_IC_ENTRY;
-                       zval_ptr_dtor(&user_func);
-                       zval_ptr_dtor(&args[0]);
-                       break;
-               }
-               BG(serialize_lock)--;
-               zval_ptr_dtor(&retval);
-               if (EG(exception)) {
-                       zend_string_release(class_name);
-                       zval_ptr_dtor(&user_func);
-                       zval_ptr_dtor(&args[0]);
-                       return 0;
-               }
-
-               /* The callback function may have defined the class */
-               BG(serialize_lock)++;
-               if ((ce = zend_lookup_class(class_name)) == NULL) {
-                       php_error_docref(NULL, E_WARNING, "Function %s() hasn't defined the class it was called for", Z_STRVAL(user_func));
-                       incomplete_class = 1;
-                       ce = PHP_IC_ENTRY;
-               }
-               BG(serialize_lock)--;
-
-               zval_ptr_dtor(&user_func);
-               zval_ptr_dtor(&args[0]);
-               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, ZSTR_VAL(class_name), len2);
-               }
-               zend_string_release(class_name);
-               return ret;
-       }
-
-       elements = object_common1(UNSERIALIZE_PASSTHRU, ce);
-
-       if (elements < 0) {
-          zend_string_release(class_name);
-          return 0;
-       }
-
-       if (incomplete_class) {
-               php_store_class_name(rval, ZSTR_VAL(class_name), len2);
-       }
-       zend_string_release(class_name);
-
-       return object_common2(UNSERIALIZE_PASSTHRU, elements);
-}
-#line 1258 "ext/standard/var_unserializer.c"
-yy77:
-       ++YYCURSOR;
-#line 768 "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;
-       }
-
-       if (*(YYCURSOR + 1) != ';') {
-               efree(str);
-               *p = YYCURSOR + 1;
-               return 0;
-       }
-
-       YYCURSOR += 2;
-       *p = YYCURSOR;
-
-       ZVAL_STR(rval, str);
-       return 1;
-}
-#line 1295 "ext/standard/var_unserializer.c"
-yy79:
-       ++YYCURSOR;
-#line 802 "ext/standard/var_unserializer.re"
-       {
-       zend_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;
-       }
-
-       array_init_size(rval, elements);
-       if (elements) {
-               /* we can't convert from packed to hash during unserialization, because
-                  reference to some zvals might be keept in var_hash (to support references) */
-               zend_hash_real_init(Z_ARRVAL_P(rval), 0);
-       }
-
-       /* The array may contain references to itself, in which case we'll be modifying an
-        * rc>1 array. This is okay, since the array is, ostensibly, only visible to
-        * unserialize (in practice unserialization handlers also see it). Ideally we should
-        * prohibit "r:" references to non-objects, as we only generate them for objects. */
-       HT_ALLOW_COW_VIOLATION(Z_ARRVAL_P(rval));
-
-       if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_P(rval), elements, 0)) {
-               return 0;
-       }
-
-       return finish_nested_data(UNSERIALIZE_PASSTHRU);
-}
-#line 1328 "ext/standard/var_unserializer.c"
-yy81:
+#line 1353 "ext/standard/var_unserializer.c"
+yy88:
        yych = *++YYCURSOR;
        if (yych <= '/') goto yy18;
        if (yych >= ':') goto yy18;
-yy82:
+yy89:
        ++YYCURSOR;
        if (YYLIMIT <= YYCURSOR) YYFILL(1);
        yych = *YYCURSOR;
        if (yych <= '/') goto yy18;
-       if (yych <= '9') goto yy82;
-       if (yych == ';') goto yy64;
-       goto yy18;
-yy84:
-       yych = *++YYCURSOR;
-       if (yych == ';') goto yy89;
-       goto yy18;
-yy85:
+       if (yych <= '9') goto yy89;
+       if (yych != ';') goto yy18;
        ++YYCURSOR;
-#line 832 "ext/standard/var_unserializer.re"
-       {
-       long elements;
-    if (!var_hash) return 0;
-
-       elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
-       if (elements < 0) {
-               return 0;
-       }
-       return object_common2(UNSERIALIZE_PASSTHRU, elements);
-}
-#line 1358 "ext/standard/var_unserializer.c"
-yy87:
-       ++YYCURSOR;
-#line 736 "ext/standard/var_unserializer.re"
+#line 622 "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;
-       }
-
-       str = (char*)YYCURSOR;
+       zend_long id;
 
-       YYCURSOR += len;
+       *p = YYCURSOR;
+       if (!var_hash) return 0;
 
-       if (*(YYCURSOR) != '"') {
-               *p = YYCURSOR;
+       id = parse_uiv(start + 2) - 1;
+       if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
                return 0;
        }
 
-       if (*(YYCURSOR + 1) != ';') {
-               *p = YYCURSOR + 1;
-               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;
        }
-
-       YYCURSOR += 2;
-       *p = YYCURSOR;
-
-       ZVAL_STRINGL(rval, str, len);
-       return 1;
-}
-#line 1393 "ext/standard/var_unserializer.c"
-yy89:
-       ++YYCURSOR;
-#line 711 "ext/standard/var_unserializer.re"
-       {
-       *p = YYCURSOR;
-
-       if (!strncmp((char*)start + 2, "NAN", 3)) {
-               ZVAL_DOUBLE(rval, ZEND_NAN);
-       } else if (!strncmp((char*)start + 2, "INF", 3)) {
-               ZVAL_DOUBLE(rval, ZEND_INFINITY);
-       } else if (!strncmp((char*)start + 2, "-INF", 4)) {
-               ZVAL_DOUBLE(rval, -ZEND_INFINITY);
+       if (Z_ISREF_P(rval_ref)) {
+               ZVAL_COPY(rval, rval_ref);
        } else {
-               ZVAL_NULL(rval);
+               ZVAL_NEW_REF(rval_ref, rval_ref);
+               ZVAL_COPY(rval, rval_ref);
        }
 
        return 1;
 }
-#line 1412 "ext/standard/var_unserializer.c"
+#line 1392 "ext/standard/var_unserializer.c"
 }
-#line 1003 "ext/standard/var_unserializer.re"
+#line 1009 "ext/standard/var_unserializer.re"
 
 
        return 0;
index 38d02cb2538cbfe6979ba7201c421393f653ad68..b75c0d2d101114f2a34c89ce0cddb55b4e0446e7 100644 (file)
@@ -761,7 +761,13 @@ use_double:
        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;
 }
 
index 577917a00747ad0e64a853e66e4d1c3d0de34c21..ae5e922ef68a91b5f065da8e422d4ce5dc73dc4f 100644 (file)
@@ -49,7 +49,13 @@ PHPAPI void php_register_variable_safe(char *var, char *strval, size_t str_len,
        assert(strval != NULL);
 
        /* Prepare value */
-       ZVAL_NEW_STR(&new_entry, zend_string_init(strval, str_len, 0));
+       if (str_len == 0) {
+               ZVAL_EMPTY_STRING(&new_entry);
+       } else if (str_len == 1) {
+               ZVAL_INTERNED_STR(&new_entry, ZSTR_CHAR((zend_uchar)*strval));
+       } else {
+               ZVAL_NEW_STR(&new_entry, zend_string_init(strval, str_len, 0));
+       }
        php_register_variable_ex(var, &new_entry, track_vars_array);
 }