summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikic@php.net>2017-01-01 14:10:49 +0100
committerNikita Popov <nikic@php.net>2017-01-01 14:10:49 +0100
commita65ad951ad95944e357703caa2001f06a4225bf6 (patch)
tree62a2992fd861d4d20d4511fe145682b817211753
parent2ba3b275948050ce600c5234b66e840b640ca5a5 (diff)
downloadphp-git-a65ad951ad95944e357703caa2001f06a4225bf6.tar.gz
FIx bug #70213
-rw-r--r--NEWS4
-rw-r--r--ext/standard/tests/serialize/bug70213.phpt30
-rw-r--r--ext/standard/var_unserializer.c973
-rw-r--r--ext/standard/var_unserializer.re2
4 files changed, 535 insertions, 474 deletions
diff --git a/NEWS b/NEWS
index e957009839..0bb1e67723 100644
--- a/NEWS
+++ b/NEWS
@@ -13,6 +13,10 @@ PHP NEWS
. Reverted fix for bug #73530 (Unsetting result set may reset other result
set). (cmb)
+- Standard:
+ . Fixed bug #70213 (Unserialize context shared on double class lookup).
+ (Taoguang Chen)
+
08 Dec 2016, PHP 5.6.29
- Mbstring:
diff --git a/ext/standard/tests/serialize/bug70213.phpt b/ext/standard/tests/serialize/bug70213.phpt
new file mode 100644
index 0000000000..c01d362be0
--- /dev/null
+++ b/ext/standard/tests/serialize/bug70213.phpt
@@ -0,0 +1,30 @@
+--TEST--
+Bug #70213: Unserialize context shared on double class lookup
+--FILE--
+<?php
+
+ini_set('unserialize_callback_func', 'evil');
+
+function evil() {
+ function __autoload($arg) {
+ var_dump(unserialize('R:1;'));
+ }
+}
+
+var_dump(unserialize('a:2:{i:0;i:42;i:1;O:4:"evil":0:{}}'));
+
+?>
+--EXPECTF--
+Notice: unserialize(): Error at offset 4 of 4 bytes in %s on line %d
+bool(false)
+
+Warning: unserialize(): Function evil() hasn't defined the class it was called for in %s on line %d
+array(2) {
+ [0]=>
+ int(42)
+ [1]=>
+ object(__PHP_Incomplete_Class)#1 (1) {
+ ["__PHP_Incomplete_Class_Name"]=>
+ string(4) "evil"
+ }
+}
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index 549149267e..584e98e275 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.13.7.5 */
+/* Generated by re2c 0.16 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
@@ -529,110 +529,505 @@ PHPAPI int php_var_unserialize(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 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 yy95;
+ ++YYCURSOR;
yy3:
-#line 861 "ext/standard/var_unserializer.re"
+#line 863 "ext/standard/var_unserializer.re"
{ return 0; }
-#line 558 "ext/standard/var_unserializer.c"
+#line 556 "ext/standard/var_unserializer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy89;
+ if (yych == ':') goto yy17;
goto yy3;
yy5:
yych = *++YYCURSOR;
- if (yych == ';') goto yy87;
+ if (yych == ';') goto yy19;
goto yy3;
yy6:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy83;
+ if (yych == ':') goto yy21;
goto yy3;
yy7:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy77;
+ if (yych == ':') goto yy22;
goto yy3;
yy8:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy53;
+ if (yych == ':') goto yy23;
goto yy3;
yy9:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy46;
+ if (yych == ':') goto yy24;
goto yy3;
yy10:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy39;
+ if (yych == ':') goto yy25;
goto yy3;
yy11:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy32;
+ if (yych == ':') goto yy26;
goto yy3;
yy12:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy25;
+ if (yych == ':') goto yy27;
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 855 "ext/standard/var_unserializer.re"
+#line 857 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
return 0; /* not sure if it should be 0 or 1 here? */
}
-#line 607 "ext/standard/var_unserializer.c"
-yy16:
- yych = *++YYCURSOR;
- goto yy3;
+#line 609 "ext/standard/var_unserializer.c"
yy17:
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy20;
+ goto yy31;
}
- if (yych == '+') goto yy19;
+ if (yych == '+') goto yy30;
yy18:
YYCURSOR = YYMARKER;
goto yy3;
yy19:
+ ++YYCURSOR;
+#line 544 "ext/standard/var_unserializer.re"
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_NULL(*rval);
+ return 1;
+}
+#line 628 "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;
+ }
+yy22:
+ yych = *++YYCURSOR;
+ if (yych == '+') goto yy36;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy37;
+ goto yy18;
+yy23:
+ yych = *++YYCURSOR;
+ if (yych == '+') goto yy39;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy40;
+ goto yy18;
+yy24:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '1') goto yy42;
+ goto yy18;
+yy25:
+ yych = *++YYCURSOR;
+ if (yych <= '/') {
+ if (yych <= ',') {
+ if (yych == '+') goto yy43;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy44;
+ if (yych <= '.') goto yy45;
+ goto yy18;
+ }
+ } else {
+ if (yych <= 'I') {
+ if (yych <= '9') goto yy46;
+ if (yych <= 'H') goto yy18;
+ goto yy48;
+ } else {
+ if (yych == 'N') goto yy49;
+ goto yy18;
+ }
+ }
+yy26:
+ yych = *++YYCURSOR;
+ if (yych <= ',') {
+ if (yych == '+') goto yy50;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy50;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy51;
+ goto yy18;
+ }
+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;
+ }
+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;
+ }
+yy29:
+ yych = *++YYCURSOR;
+ if (yych == '+') goto yy59;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy60;
+ goto yy18;
+yy30:
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy20;
+ goto yy31;
}
goto yy18;
-yy20:
+yy31:
++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy20;
+ goto yy31;
}
if (yych <= '/') goto yy18;
- if (yych >= ';') goto yy18;
+ if (yych <= ':') goto yy62;
+ goto yy18;
+yy33:
yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy34:
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy34;
+ if (yych == ';') goto yy63;
+ goto yy18;
+yy36:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy37:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy37;
+ if (yych <= ':') goto yy65;
+ goto yy18;
+yy39:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy40:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy40;
+ if (yych <= ':') goto yy66;
+ goto yy18;
+yy42:
+ yych = *++YYCURSOR;
+ if (yych == ';') goto yy67;
+ goto yy18;
+yy43:
+ yych = *++YYCURSOR;
+ if (yych == '.') goto yy45;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy46;
+ goto yy18;
+yy44:
+ yych = *++YYCURSOR;
+ if (yych <= '/') {
+ if (yych != '.') goto yy18;
+ } else {
+ if (yych <= '9') goto yy46;
+ if (yych == 'I') goto yy48;
+ goto yy18;
+ }
+yy45:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy69;
+ goto yy18;
+yy46:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ if (yych <= ':') {
+ if (yych <= '.') {
+ if (yych <= '-') goto yy18;
+ goto yy69;
+ } else {
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy46;
+ goto yy18;
+ }
+ } else {
+ if (yych <= 'E') {
+ if (yych <= ';') goto yy71;
+ if (yych <= 'D') goto yy18;
+ goto yy73;
+ } else {
+ if (yych == 'e') goto yy73;
+ goto yy18;
+ }
+ }
+yy48:
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy74;
+ goto yy18;
+yy49:
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy75;
+ goto yy18;
+yy50:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy51:
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy51;
+ if (yych == ';') goto yy76;
+ goto yy18;
+yy53:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy54:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy54;
+ if (yych <= ':') goto yy78;
+ goto yy18;
+yy56:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy57:
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy57;
+ if (yych == ';') goto yy79;
+ goto yy18;
+yy59:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy60:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy60;
+ if (yych <= ':') goto yy81;
+ goto yy18;
+yy62:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy82;
+ goto yy18;
+yy63:
+ ++YYCURSOR;
+#line 500 "ext/standard/var_unserializer.re"
+ {
+ long id;
+
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ id = parse_iv(start + 2) - 1;
+ if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+ return 0;
+ }
+
+ if (*rval != NULL) {
+ var_push_dtor_no_addref(var_hash, rval);
+ }
+ *rval = *rval_ref;
+ Z_ADDREF_PP(rval);
+ Z_SET_ISREF_PP(rval);
+
+ return 1;
+}
+#line 899 "ext/standard/var_unserializer.c"
+yy65:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy84;
+ goto yy18;
+yy66:
+ yych = *++YYCURSOR;
+ if (yych == '{') goto yy86;
+ goto yy18;
+yy67:
+ ++YYCURSOR;
+#line 551 "ext/standard/var_unserializer.re"
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_BOOL(*rval, parse_iv(start + 2));
+ return 1;
+}
+#line 917 "ext/standard/var_unserializer.c"
+yy69:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
+ yych = *YYCURSOR;
+ if (yych <= ';') {
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy69;
+ if (yych <= ':') goto yy18;
+ } else {
+ if (yych <= 'E') {
+ if (yych <= 'D') goto yy18;
+ goto yy73;
+ } else {
+ if (yych == 'e') goto yy73;
+ goto yy18;
+ }
+ }
+yy71:
+ ++YYCURSOR;
+#line 600 "ext/standard/var_unserializer.re"
+ {
+#if SIZEOF_LONG == 4
+use_double:
+#endif
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
+ return 1;
+}
+#line 947 "ext/standard/var_unserializer.c"
+yy73:
+ yych = *++YYCURSOR;
+ if (yych <= ',') {
+ if (yych == '+') goto yy88;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy88;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy89;
+ goto yy18;
+ }
+yy74:
+ yych = *++YYCURSOR;
+ if (yych == 'F') goto yy91;
+ goto yy18;
+yy75:
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy91;
+ goto yy18;
+yy76:
+ ++YYCURSOR;
+#line 558 "ext/standard/var_unserializer.re"
+ {
+#if SIZEOF_LONG == 4
+ int digits = YYCURSOR - start - 3;
+
+ if (start[2] == '-' || start[2] == '+') {
+ digits--;
+ }
+
+ /* Use double for large long values that were serialized on a 64-bit system */
+ if (digits >= MAX_LENGTH_OF_LONG - 1) {
+ if (digits == MAX_LENGTH_OF_LONG - 1) {
+ int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
+
+ if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
+ goto use_double;
+ }
+ } else {
+ goto use_double;
+ }
+ }
+#endif
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_LONG(*rval, parse_iv(start + 2));
+ return 1;
+}
+#line 996 "ext/standard/var_unserializer.c"
+yy78:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy92;
+ goto yy18;
+yy79:
+ ++YYCURSOR;
+#line 521 "ext/standard/var_unserializer.re"
+ {
+ long id;
+
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ id = parse_iv(start + 2) - 1;
+ if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+ return 0;
+ }
+
+ if (*rval == *rval_ref) return 0;
+
+ if (*rval != NULL) {
+ var_push_dtor_no_addref(var_hash, rval);
+ }
+ *rval = *rval_ref;
+ Z_ADDREF_PP(rval);
+ Z_UNSET_ISREF_PP(rval);
+
+ return 1;
+}
+#line 1026 "ext/standard/var_unserializer.c"
+yy81:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy94;
+ goto yy18;
+yy82:
++YYCURSOR;
#line 708 "ext/standard/var_unserializer.re"
{
@@ -745,6 +1140,7 @@ yy20:
}
/* The callback function may have defined the class */
+ BG(serialize_lock)++;
if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
ce = *pce;
} else {
@@ -752,6 +1148,7 @@ yy20:
incomplete_class = 1;
ce = PHP_IC_ENTRY;
}
+ BG(serialize_lock)--;
zval_ptr_dtor(&user_func);
zval_ptr_dtor(&arg_func_name);
@@ -781,102 +1178,8 @@ yy20:
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
-#line 785 "ext/standard/var_unserializer.c"
-yy25:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy26;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy27;
- goto yy18;
- }
-yy26:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy27:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy27;
- if (yych >= ';') goto yy18;
- yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
- ++YYCURSOR;
-#line 699 "ext/standard/var_unserializer.re"
- {
- if (!var_hash) return 0;
-
- INIT_PZVAL(*rval);
-
- return object_common2(UNSERIALIZE_PASSTHRU,
- object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
-}
-#line 819 "ext/standard/var_unserializer.c"
-yy32:
- yych = *++YYCURSOR;
- if (yych == '+') goto yy33;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy34;
- goto yy18;
-yy33:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy34:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy34;
- if (yych >= ';') goto yy18;
- yych = *++YYCURSOR;
- if (yych != '{') goto yy18;
- ++YYCURSOR;
-#line 678 "ext/standard/var_unserializer.re"
- {
- long elements = parse_iv(start + 2);
- /* use iv() not uiv() in order to check data range */
- *p = YYCURSOR;
- if (!var_hash) return 0;
-
- if (elements < 0) {
- return 0;
- }
-
- INIT_PZVAL(*rval);
-
- array_init_size(*rval, elements);
-
- if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
- return 0;
- }
-
- return finish_nested_data(UNSERIALIZE_PASSTHRU);
-}
-#line 861 "ext/standard/var_unserializer.c"
-yy39:
- yych = *++YYCURSOR;
- if (yych == '+') goto yy40;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy41;
- goto yy18;
-yy40:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy41:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy41;
- if (yych >= ';') goto yy18;
- yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
+#line 1182 "ext/standard/var_unserializer.c"
+yy84:
++YYCURSOR;
#line 643 "ext/standard/var_unserializer.re"
{
@@ -913,26 +1216,66 @@ yy41:
ZVAL_STRINGL(*rval, str, len, 0);
return 1;
}
-#line 917 "ext/standard/var_unserializer.c"
-yy46:
- yych = *++YYCURSOR;
- if (yych == '+') goto yy47;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy48;
- goto yy18;
-yy47:
+#line 1220 "ext/standard/var_unserializer.c"
+yy86:
+ ++YYCURSOR;
+#line 678 "ext/standard/var_unserializer.re"
+ {
+ long elements = parse_iv(start + 2);
+ /* use iv() not uiv() in order to check data range */
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ if (elements < 0) {
+ return 0;
+ }
+
+ INIT_PZVAL(*rval);
+
+ array_init_size(*rval, elements);
+
+ if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
+ return 0;
+ }
+
+ return finish_nested_data(UNSERIALIZE_PASSTHRU);
+}
+#line 1244 "ext/standard/var_unserializer.c"
+yy88:
yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy48:
+ if (yych <= ',') {
+ if (yych == '+') goto yy96;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy96;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+ }
+yy89:
++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy48;
- if (yych >= ';') goto yy18;
+ if (yych <= '9') goto yy89;
+ if (yych == ';') goto yy71;
+ goto yy18;
+yy91:
yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
+ if (yych == ';') goto yy97;
+ goto yy18;
+yy92:
+ ++YYCURSOR;
+#line 699 "ext/standard/var_unserializer.re"
+ {
+ if (!var_hash) return 0;
+
+ INIT_PZVAL(*rval);
+
+ return object_common2(UNSERIALIZE_PASSTHRU,
+ object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR));
+}
+#line 1278 "ext/standard/var_unserializer.c"
+yy94:
++YYCURSOR;
#line 610 "ext/standard/var_unserializer.re"
{
@@ -967,162 +1310,13 @@ yy48:
ZVAL_STRINGL(*rval, str, len, 1);
return 1;
}
-#line 971 "ext/standard/var_unserializer.c"
-yy53:
- yych = *++YYCURSOR;
- if (yych <= '/') {
- if (yych <= ',') {
- if (yych == '+') goto yy57;
- goto yy18;
- } else {
- if (yych <= '-') goto yy55;
- if (yych <= '.') goto yy60;
- goto yy18;
- }
- } else {
- if (yych <= 'I') {
- if (yych <= '9') goto yy58;
- if (yych <= 'H') goto yy18;
- goto yy56;
- } else {
- if (yych != 'N') goto yy18;
- }
- }
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy76;
- goto yy18;
-yy55:
- yych = *++YYCURSOR;
- if (yych <= '/') {
- if (yych == '.') goto yy60;
- goto yy18;
- } else {
- if (yych <= '9') goto yy58;
- if (yych != 'I') goto yy18;
- }
-yy56:
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy72;
- goto yy18;
-yy57:
- yych = *++YYCURSOR;
- if (yych == '.') goto yy60;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy58:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
- yych = *YYCURSOR;
- if (yych <= ':') {
- if (yych <= '.') {
- if (yych <= '-') goto yy18;
- goto yy70;
- } else {
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy58;
- goto yy18;
- }
- } else {
- if (yych <= 'E') {
- if (yych <= ';') goto yy63;
- if (yych <= 'D') goto yy18;
- goto yy65;
- } else {
- if (yych == 'e') goto yy65;
- goto yy18;
- }
- }
-yy60:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy61:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
- yych = *YYCURSOR;
- if (yych <= ';') {
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy61;
- if (yych <= ':') goto yy18;
- } else {
- if (yych <= 'E') {
- if (yych <= 'D') goto yy18;
- goto yy65;
- } else {
- if (yych == 'e') goto yy65;
- goto yy18;
- }
- }
-yy63:
- ++YYCURSOR;
-#line 600 "ext/standard/var_unserializer.re"
- {
-#if SIZEOF_LONG == 4
-use_double:
-#endif
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL));
- return 1;
-}
-#line 1069 "ext/standard/var_unserializer.c"
-yy65:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy66;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy67;
- goto yy18;
- }
-yy66:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych == '+') goto yy69;
- goto yy18;
- } else {
- if (yych <= '-') goto yy69;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
- }
-yy67:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy67;
- if (yych == ';') goto yy63;
- goto yy18;
-yy69:
+#line 1314 "ext/standard/var_unserializer.c"
+yy96:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy67;
+ if (yych <= '9') goto yy89;
goto yy18;
-yy70:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 4) YYFILL(4);
- yych = *YYCURSOR;
- if (yych <= ';') {
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy70;
- if (yych <= ':') goto yy18;
- goto yy63;
- } else {
- if (yych <= 'E') {
- if (yych <= 'D') goto yy18;
- goto yy65;
- } else {
- if (yych == 'e') goto yy65;
- goto yy18;
- }
- }
-yy72:
- yych = *++YYCURSOR;
- if (yych != 'F') goto yy18;
-yy73:
- yych = *++YYCURSOR;
- if (yych != ';') goto yy18;
+yy97:
++YYCURSOR;
#line 585 "ext/standard/var_unserializer.re"
{
@@ -1139,178 +1333,9 @@ yy73:
return 1;
}
-#line 1143 "ext/standard/var_unserializer.c"
-yy76:
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy73;
- goto yy18;
-yy77:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy78;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy79;
- goto yy18;
- }
-yy78:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy79:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy79;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 558 "ext/standard/var_unserializer.re"
- {
-#if SIZEOF_LONG == 4
- int digits = YYCURSOR - start - 3;
-
- if (start[2] == '-' || start[2] == '+') {
- digits--;
- }
-
- /* Use double for large long values that were serialized on a 64-bit system */
- if (digits >= MAX_LENGTH_OF_LONG - 1) {
- if (digits == MAX_LENGTH_OF_LONG - 1) {
- int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
-
- if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
- goto use_double;
- }
- } else {
- goto use_double;
- }
- }
-#endif
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_LONG(*rval, parse_iv(start + 2));
- return 1;
-}
-#line 1197 "ext/standard/var_unserializer.c"
-yy83:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= '2') goto yy18;
- yych = *++YYCURSOR;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 551 "ext/standard/var_unserializer.re"
- {
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_BOOL(*rval, parse_iv(start + 2));
- return 1;
-}
-#line 1212 "ext/standard/var_unserializer.c"
-yy87:
- ++YYCURSOR;
-#line 544 "ext/standard/var_unserializer.re"
- {
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_NULL(*rval);
- return 1;
-}
-#line 1222 "ext/standard/var_unserializer.c"
-yy89:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy90;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy91;
- goto yy18;
- }
-yy90:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy91:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy91;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 521 "ext/standard/var_unserializer.re"
- {
- long id;
-
- *p = YYCURSOR;
- if (!var_hash) return 0;
-
- id = parse_iv(start + 2) - 1;
- if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
- return 0;
- }
-
- if (*rval == *rval_ref) return 0;
-
- if (*rval != NULL) {
- var_push_dtor_no_addref(var_hash, rval);
- }
- *rval = *rval_ref;
- Z_ADDREF_PP(rval);
- Z_UNSET_ISREF_PP(rval);
-
- return 1;
-}
-#line 1268 "ext/standard/var_unserializer.c"
-yy95:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy96;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy97;
- goto yy18;
- }
-yy96:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy97:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy97;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 500 "ext/standard/var_unserializer.re"
- {
- long id;
-
- *p = YYCURSOR;
- if (!var_hash) return 0;
-
- id = parse_iv(start + 2) - 1;
- if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
- return 0;
- }
-
- if (*rval != NULL) {
- var_push_dtor_no_addref(var_hash, rval);
- }
- *rval = *rval_ref;
- Z_ADDREF_PP(rval);
- Z_SET_ISREF_PP(rval);
-
- return 1;
-}
-#line 1312 "ext/standard/var_unserializer.c"
+#line 1337 "ext/standard/var_unserializer.c"
}
-#line 863 "ext/standard/var_unserializer.re"
+#line 865 "ext/standard/var_unserializer.re"
return 0;
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index ce84bf5eb4..9eeba79f3f 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -815,6 +815,7 @@ object ":" uiv ":" ["] {
}
/* The callback function may have defined the class */
+ BG(serialize_lock)++;
if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) {
ce = *pce;
} else {
@@ -822,6 +823,7 @@ object ":" uiv ":" ["] {
incomplete_class = 1;
ce = PHP_IC_ENTRY;
}
+ BG(serialize_lock)--;
zval_ptr_dtor(&user_func);
zval_ptr_dtor(&arg_func_name);