com php-src: Use interned empty and "one char" strings.: 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_unserialize r.c ext/standard/var_unserializer.re main/php_varia bles.c

[email protected] (Dmitry Stogov)
Newsgroups php.cvs
Message-ID <[email protected]>
Commit:    a08723d3d313445191470c19e12235a56165600a
Author:    Dmitry Stogov <[email protected]>         Thu, 18 May 2017 17:59:59 +0300
Parents:   b1a07d430bf8292a835bd04b553bc1867d6d6972
Branches:  master

Link:       http://git.php.net/?p=php-src.git;a=commitdiff;h=a08723d3d313445191470c19e12235a56165600a

Log:
Use interned empty and "one char" strings.

Changed paths:
  M  Zend/zend_operators.c
  M  ext/mysqlnd/mysqlnd_wireprotocol.c
  M  ext/standard/array.c
  M  ext/standard/basic_functions.c
  M  ext/standard/string.c
  M  ext/standard/var_unserializer.c
  M  ext/standard/var_unserializer.re
  M  main/php_variables.c
diff_a08723d3d313445191470c19e12235a56165600a.txt (text/plain, 35.5 KB)
diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c
index 41d1ca6..ea9e506 100644
--- a/Zend/zend_operators.c
+++ b/Zend/zend_operators.c
@@ -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);
+	}
 }
 /* }}} */
 
diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c
index 90ae615..2a2cd9b 100644
--- a/ext/mysqlnd/mysqlnd_wireprotocol.c
+++ b/ext/mysqlnd/mysqlnd_wireprotocol.c
@@ -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);
 			}
diff --git a/ext/standard/array.c b/ext/standard/array.c
index 69c98d8..2744ee3 100644
--- a/ext/standard/array.c
+++ b/ext/standard/array.c
@@ -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);
diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c
index 56131e7..3d911ce 100644
--- a/ext/standard/basic_functions.c
+++ b/ext/standard/basic_functions.c
@@ -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;
 	}
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 4ae3546..83f5901 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -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;
 	}
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index a1f505c..612c34a 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -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;
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index 38d02cb..b75c0d2 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -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;
 }
 
diff --git a/main/php_variables.c b/main/php_variables.c
index 577917a..ae5e922 100644
--- a/main/php_variables.c
+++ b/main/php_variables.c
@@ -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);
 }
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.