summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2017-06-25 21:15:26 +0200
committerStanislav Malyshev <stas@php.net>2017-07-04 19:06:16 -0700
commitf8c514ba6b7962a219296a837b2dbc22f749e736 (patch)
treebe07d6ea1086d14e010ebf67288b799e3e2bdacb
parent8dc4f4dc9e44d1cbfe4654aa6e0dc27c94913938 (diff)
downloadphp-git-f8c514ba6b7962a219296a837b2dbc22f749e736.tar.gz
Fixed bug #74111
-rw-r--r--ext/standard/tests/serialize/bug25378.phpt2
-rw-r--r--ext/standard/tests/serialize/bug74111.phpt10
-rw-r--r--ext/standard/var_unserializer.c995
-rw-r--r--ext/standard/var_unserializer.re11
4 files changed, 501 insertions, 517 deletions
diff --git a/ext/standard/tests/serialize/bug25378.phpt b/ext/standard/tests/serialize/bug25378.phpt
index e865b96e99..e95a427006 100644
--- a/ext/standard/tests/serialize/bug25378.phpt
+++ b/ext/standard/tests/serialize/bug25378.phpt
@@ -42,7 +42,7 @@ bool(false)
Notice: unserialize(): Error at offset 17 of 33 bytes in %sbug25378.php on line %d
bool(false)
-Notice: unserialize(): Error at offset 33 of 32 bytes in %sbug25378.php on line %d
+Notice: unserialize(): Error at offset 32 of 32 bytes in %sbug25378.php on line %d
bool(false)
Notice: unserialize(): Error at offset 2 of 13 bytes in %sbug25378.php on line %d
diff --git a/ext/standard/tests/serialize/bug74111.phpt b/ext/standard/tests/serialize/bug74111.phpt
new file mode 100644
index 0000000000..62922bea55
--- /dev/null
+++ b/ext/standard/tests/serialize/bug74111.phpt
@@ -0,0 +1,10 @@
+--TEST--
+Bug #74111: Heap buffer overread (READ: 1) finish_nested_data from unserialize
+--FILE--
+<?php
+$s = 'O:8:"stdClass":00000000';
+var_dump(unserialize($s));
+?>
+--EXPECTF--
+Notice: unserialize(): Error at offset 25 of 23 bytes in %s on line %d
+bool(false)
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index 6706866f2b..f94d1763bb 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.15.3 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
@@ -406,13 +406,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
{
- if (*((*p)++) == '}')
- return 1;
+ if (*p >= max || **p != '}') {
+ return 0;
+ }
-#if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
- zval_ptr_dtor(rval);
-#endif
- return 0;
+ (*p)++;
+ return 1;
}
static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)
@@ -529,7 +528,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
-#line 533 "ext/standard/var_unserializer.c"
+#line 532 "ext/standard/var_unserializer.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -570,503 +569,107 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER)
yych = *YYCURSOR;
switch (yych) {
case 'C':
- case 'O': goto yy4;
+ case 'O': goto yy13;
case 'N': goto yy5;
- case 'R': goto yy6;
- case 'S': goto yy7;
- case 'a': goto yy8;
- case 'b': goto yy9;
- case 'd': goto yy10;
- case 'i': goto yy11;
+ case 'R': goto yy2;
+ case 'S': goto yy10;
+ case 'a': goto yy11;
+ case 'b': goto yy6;
+ case 'd': goto yy8;
+ case 'i': goto yy7;
case 'o': goto yy12;
- case 'r': goto yy13;
- case 's': goto yy14;
- case '}': goto yy15;
- default: goto yy2;
+ case 'r': goto yy4;
+ case 's': goto yy9;
+ case '}': goto yy14;
+ default: goto yy16;
}
yy2:
- ++YYCURSOR;
+ yych = *(YYMARKER = ++YYCURSOR);
+ if (yych == ':') goto yy95;
yy3:
-#line 909 "ext/standard/var_unserializer.re"
+#line 908 "ext/standard/var_unserializer.re"
{ return 0; }
#line 593 "ext/standard/var_unserializer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy17;
+ if (yych == ':') goto yy89;
goto yy3;
yy5:
yych = *++YYCURSOR;
- if (yych == ';') goto yy19;
+ if (yych == ';') goto yy87;
goto yy3;
yy6:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy21;
+ if (yych == ':') goto yy83;
goto yy3;
yy7:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy22;
+ if (yych == ':') goto yy77;
goto yy3;
yy8:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy23;
+ if (yych == ':') goto yy53;
goto yy3;
yy9:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy24;
+ if (yych == ':') goto yy46;
goto yy3;
yy10:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy25;
+ if (yych == ':') goto yy39;
goto yy3;
yy11:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy26;
+ if (yych == ':') goto yy32;
goto yy3;
yy12:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy27;
+ if (yych == ':') goto yy25;
goto yy3;
yy13:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy28;
+ if (yych == ':') goto yy17;
goto yy3;
yy14:
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy29;
- goto yy3;
-yy15:
++YYCURSOR;
-#line 903 "ext/standard/var_unserializer.re"
+#line 902 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Unexpected end of serialized data");
return 0; /* not sure if it should be 0 or 1 here? */
}
-#line 646 "ext/standard/var_unserializer.c"
+#line 642 "ext/standard/var_unserializer.c"
+yy16:
+ yych = *++YYCURSOR;
+ goto yy3;
yy17:
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy31;
+ goto yy20;
}
- if (yych == '+') goto yy30;
+ if (yych == '+') goto yy19;
yy18:
YYCURSOR = YYMARKER;
goto yy3;
yy19:
- ++YYCURSOR;
-#line 581 "ext/standard/var_unserializer.re"
- {
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_NULL(*rval);
- return 1;
-}
-#line 665 "ext/standard/var_unserializer.c"
-yy21:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych == '+') goto yy33;
- goto yy18;
- } else {
- if (yych <= '-') goto yy33;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy34;
- goto yy18;
- }
-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 yy31;
+ goto yy20;
}
goto yy18;
-yy31:
+yy20:
++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy31;
- }
- if (yych <= '/') goto yy18;
- if (yych <= ':') goto yy62;
- goto yy18;
-yy33:
- yych = *++YYCURSOR;
- 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;
+ goto yy20;
}
-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:
+ if (yych >= ';') goto yy18;
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:
+ if (yych != '"') goto yy18;
++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 537 "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 936 "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 588 "ext/standard/var_unserializer.re"
- {
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_BOOL(*rval, parse_iv(start + 2));
- return 1;
-}
-#line 954 "ext/standard/var_unserializer.c"
-yy69:
- ++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 637 "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 984 "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 595 "ext/standard/var_unserializer.re"
- {
-#if SIZEOF_LONG == 4
- int digits = YYCURSOR - start - 3;
-
- if (start[2] == '-' || start[2] == '+') {
- digits--;
- }
-
- /* Use double for large long values that were serialized on a 64-bit system */
- if (digits >= MAX_LENGTH_OF_LONG - 1) {
- if (digits == MAX_LENGTH_OF_LONG - 1) {
- int cmp = strncmp(YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
-
- if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
- goto use_double;
- }
- } else {
- goto use_double;
- }
- }
-#endif
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
- ZVAL_LONG(*rval, parse_iv(start + 2));
- return 1;
-}
-#line 1033 "ext/standard/var_unserializer.c"
-yy78:
- yych = *++YYCURSOR;
- if (yych == '"') goto yy92;
- goto yy18;
-yy79:
- ++YYCURSOR;
-#line 558 "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 1063 "ext/standard/var_unserializer.c"
-yy81:
- yych = *++YYCURSOR;
- if (yych == '"') goto yy94;
- goto yy18;
-yy82:
- ++YYCURSOR;
-#line 749 "ext/standard/var_unserializer.re"
+#line 748 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
long elements;
@@ -1220,10 +823,108 @@ yy82:
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
-#line 1224 "ext/standard/var_unserializer.c"
-yy84:
+#line 827 "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 735 "ext/standard/var_unserializer.re"
+ {
+ long elements;
+ if (!var_hash) return 0;
+
+ INIT_PZVAL(*rval);
+
+ elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
+ if (elements < 0) {
+ return 0;
+ }
+ return object_common2(UNSERIALIZE_PASSTHRU, elements);
+}
+#line 865 "ext/standard/var_unserializer.c"
+yy32:
+ yych = *++YYCURSOR;
+ if (yych == '+') goto yy33;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy34;
+ 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 714 "ext/standard/var_unserializer.re"
+ {
+ long elements = parse_iv(start + 2);
+ /* use iv() not uiv() in order to check data range */
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ if (elements < 0) {
+ return 0;
+ }
+
+ 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 907 "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;
++YYCURSOR;
-#line 680 "ext/standard/var_unserializer.re"
+#line 679 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@@ -1258,130 +959,404 @@ yy84:
ZVAL_STRINGL(*rval, str, len, 0);
return 1;
}
-#line 1262 "ext/standard/var_unserializer.c"
-yy86:
+#line 963 "ext/standard/var_unserializer.c"
+yy46:
+ yych = *++YYCURSOR;
+ if (yych == '+') goto yy47;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy48;
+ goto yy18;
+yy47:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= ':') goto yy18;
+yy48:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy48;
+ if (yych >= ';') goto yy18;
+ yych = *++YYCURSOR;
+ if (yych != '"') goto yy18;
++YYCURSOR;
-#line 715 "ext/standard/var_unserializer.re"
+#line 646 "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;
+ size_t len, maxlen;
+ char *str;
- if (elements < 0) {
+ len = parse_uiv(start + 2);
+ maxlen = max - YYCURSOR;
+ if (maxlen < len) {
+ *p = start + 2;
return 0;
}
- INIT_PZVAL(*rval);
+ str = (char*)YYCURSOR;
- array_init_size(*rval, elements);
+ YYCURSOR += len;
- if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) {
+ if (*(YYCURSOR) != '"') {
+ *p = YYCURSOR;
return 0;
}
- return finish_nested_data(UNSERIALIZE_PASSTHRU);
+ if (*(YYCURSOR + 1) != ';') {
+ *p = YYCURSOR + 1;
+ return 0;
+ }
+
+ YYCURSOR += 2;
+ *p = YYCURSOR;
+
+ INIT_PZVAL(*rval);
+ ZVAL_STRINGL(*rval, str, len, 1);
+ return 1;
}
-#line 1286 "ext/standard/var_unserializer.c"
-yy88:
+#line 1017 "ext/standard/var_unserializer.c"
+yy53:
+ yych = *++YYCURSOR;
+ if (yych <= '/') {
+ if (yych <= ',') {
+ if (yych == '+') goto yy57;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy55;
+ if (yych <= '.') goto yy60;
+ goto yy18;
+ }
+ } else {
+ if (yych <= 'I') {
+ if (yych <= '9') goto yy58;
+ if (yych <= 'H') goto yy18;
+ goto yy56;
+ } else {
+ if (yych != 'N') goto yy18;
+ }
+ }
+ yych = *++YYCURSOR;
+ if (yych == '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 636 "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 1115 "ext/standard/var_unserializer.c"
+yy65:
yych = *++YYCURSOR;
if (yych <= ',') {
- if (yych == '+') goto yy96;
+ 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 yy96;
+ if (yych <= '-') goto yy69;
if (yych <= '/') goto yy18;
if (yych >= ':') goto yy18;
}
-yy89:
+yy67:
++YYCURSOR;
if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy89;
- if (yych == ';') goto yy71;
+ if (yych <= '9') goto yy67;
+ if (yych == ';') goto yy63;
goto yy18;
-yy91:
+yy69:
yych = *++YYCURSOR;
- if (yych == ';') goto yy97;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy67;
goto yy18;
-yy92:
+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;
++YYCURSOR;
-#line 736 "ext/standard/var_unserializer.re"
+#line 621 "ext/standard/var_unserializer.re"
{
- long elements;
- if (!var_hash) return 0;
-
+ *p = YYCURSOR;
INIT_PZVAL(*rval);
- elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
- if (elements < 0) {
- return 0;
+ if (!strncmp(start + 2, "NAN", 3)) {
+ ZVAL_DOUBLE(*rval, php_get_nan());
+ } else if (!strncmp(start + 2, "INF", 3)) {
+ ZVAL_DOUBLE(*rval, php_get_inf());
+ } else if (!strncmp(start + 2, "-INF", 4)) {
+ ZVAL_DOUBLE(*rval, -php_get_inf());
}
- return object_common2(UNSERIALIZE_PASSTHRU, elements);
+
+ return 1;
}
-#line 1324 "ext/standard/var_unserializer.c"
-yy94:
+#line 1189 "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;
-#line 647 "ext/standard/var_unserializer.re"
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy79;
+ if (yych != ';') goto yy18;
+ ++YYCURSOR;
+#line 594 "ext/standard/var_unserializer.re"
{
- size_t len, maxlen;
- char *str;
+#if SIZEOF_LONG == 4
+ int digits = YYCURSOR - start - 3;
- len = parse_uiv(start + 2);
- maxlen = max - YYCURSOR;
- if (maxlen < len) {
- *p = start + 2;
- return 0;
+ if (start[2] == '-' || start[2] == '+') {
+ digits--;
}
- str = (char*)YYCURSOR;
-
- YYCURSOR += len;
+ /* 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 (*(YYCURSOR) != '"') {
- *p = YYCURSOR;
- return 0;
+ 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 1243 "ext/standard/var_unserializer.c"
+yy83:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych >= '2') goto yy18;
+ yych = *++YYCURSOR;
+ if (yych != ';') goto yy18;
+ ++YYCURSOR;
+#line 587 "ext/standard/var_unserializer.re"
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_BOOL(*rval, parse_iv(start + 2));
+ return 1;
+}
+#line 1258 "ext/standard/var_unserializer.c"
+yy87:
+ ++YYCURSOR;
+#line 580 "ext/standard/var_unserializer.re"
+ {
+ *p = YYCURSOR;
+ INIT_PZVAL(*rval);
+ ZVAL_NULL(*rval);
+ return 1;
+}
+#line 1268 "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 557 "ext/standard/var_unserializer.re"
+ {
+ long id;
- if (*(YYCURSOR + 1) != ';') {
- *p = YYCURSOR + 1;
+ *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;
}
- YYCURSOR += 2;
- *p = YYCURSOR;
+ 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);
- INIT_PZVAL(*rval);
- ZVAL_STRINGL(*rval, str, len, 1);
return 1;
}
-#line 1360 "ext/standard/var_unserializer.c"
+#line 1314 "ext/standard/var_unserializer.c"
+yy95:
+ yych = *++YYCURSOR;
+ if (yych <= ',') {
+ if (yych != '+') goto yy18;
+ } else {
+ if (yych <= '-') goto yy96;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy97;
+ goto yy18;
+ }
yy96:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy89;
- goto yy18;
+ if (yych >= ':') goto yy18;
yy97:
++YYCURSOR;
-#line 622 "ext/standard/var_unserializer.re"
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy97;
+ if (yych != ';') goto yy18;
+ ++YYCURSOR;
+#line 536 "ext/standard/var_unserializer.re"
{
- *p = YYCURSOR;
- INIT_PZVAL(*rval);
+ long id;
- if (!strncmp(start + 2, "NAN", 3)) {
- ZVAL_DOUBLE(*rval, php_get_nan());
- } else if (!strncmp(start + 2, "INF", 3)) {
- ZVAL_DOUBLE(*rval, php_get_inf());
- } else if (!strncmp(start + 2, "-INF", 4)) {
- ZVAL_DOUBLE(*rval, -php_get_inf());
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ id = parse_iv(start + 2) - 1;
+ if (id == -1 || var_access(var_hash, id, &rval_ref) != SUCCESS) {
+ return 0;
+ }
+
+ if (*rval != NULL) {
+ var_push_dtor_no_addref(var_hash, rval);
}
+ *rval = *rval_ref;
+ Z_ADDREF_PP(rval);
+ Z_SET_ISREF_PP(rval);
return 1;
}
-#line 1383 "ext/standard/var_unserializer.c"
+#line 1358 "ext/standard/var_unserializer.c"
}
-#line 911 "ext/standard/var_unserializer.re"
+#line 910 "ext/standard/var_unserializer.re"
return 0;
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index bb0000ba5f..1707ca5cc1 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -410,13 +410,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, long
static inline int finish_nested_data(UNSERIALIZE_PARAMETER)
{
- if (*((*p)++) == '}')
- return 1;
+ if (*p >= max || **p != '}') {
+ return 0;
+ }
-#if SOMETHING_NEW_MIGHT_LEAD_TO_CRASH_ENABLE_IF_YOU_ARE_BRAVE
- zval_ptr_dtor(rval);
-#endif
- return 0;
+ (*p)++;
+ return 1;
}
static inline int object_custom(UNSERIALIZE_PARAMETER, zend_class_entry *ce)