summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Popov <nikita.ppv@gmail.com>2017-08-12 13:17:24 +0200
committerNikita Popov <nikita.ppv@gmail.com>2017-08-12 13:17:24 +0200
commita871badf2a7a28dc3d69b7e165bcf8a83feac706 (patch)
treeb879f63a6d9ec00c9a34e0b5d1724ba5fbc9e39b
parentf877b86604e9c7e8642e1a6dd44954cb1f21ea34 (diff)
parent4fb7665c099eb2e2ee75ead8e77479866ab01b2a (diff)
downloadphp-git-a871badf2a7a28dc3d69b7e165bcf8a83feac706.tar.gz
Merge branch 'PHP-7.1' into PHP-7.2
-rw-r--r--NEWS6
-rw-r--r--ext/standard/tests/serialize/bug74103.phpt9
-rw-r--r--ext/standard/tests/serialize/bug75054.phpt12
-rw-r--r--ext/standard/var_unserializer.c883
-rw-r--r--ext/standard/var_unserializer.re19
5 files changed, 480 insertions, 449 deletions
diff --git a/NEWS b/NEWS
index fb15b63157..cd0ce8a9db 100644
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,12 @@ PHP NEWS
spl_autoload_functions results). (Laruence)
. Added spl_object_id(). (Tyson Andre)
+- Standard:
+ . Fixed bug #74103 (heap-use-after-free when unserializing invalid array
+ size). (Nikita)
+ . Fixed bug #75054 (A Denial of Service Vulnerability was found when
+ performing deserialization). (Nikita)
+
- XMLRPC:
. Fixed bug #74975 (Incorrect xmlrpc serialization for classes with declared
properties). (blar)
diff --git a/ext/standard/tests/serialize/bug74103.phpt b/ext/standard/tests/serialize/bug74103.phpt
new file mode 100644
index 0000000000..3d474b31b1
--- /dev/null
+++ b/ext/standard/tests/serialize/bug74103.phpt
@@ -0,0 +1,9 @@
+--TEST--
+Bug #74103: heap-use-after-free when unserializing invalid array size
+--FILE--
+<?php
+var_dump(unserialize('a:7:{i:0;i:04;s:1:"a";i:2;i:00009617006;i:4;s:1:"a";i:4;s:1:"a";R:5;s:1:"7";R:3;s:1:"a";R:5;;s:18;}}'));
+?>
+--EXPECTF--
+Notice: unserialize(): Error at offset 68 of 100 bytes in %s on line %d
+bool(false)
diff --git a/ext/standard/tests/serialize/bug75054.phpt b/ext/standard/tests/serialize/bug75054.phpt
new file mode 100644
index 0000000000..51f5692f44
--- /dev/null
+++ b/ext/standard/tests/serialize/bug75054.phpt
@@ -0,0 +1,12 @@
+--TEST--
+Bug #75054: A Denial of Service Vulnerability was found when performing deserialization
+--FILE--
+<?php
+$poc = 'a:9:{i:0;s:4:"0000";i:0;s:4:"0000";i:0;R:2;s:4:"5003";R:2;s:4:"0000";R:2;s:4:"0000";R:2;s:4:"';
+$poc .= "\x06";
+$poc .= '000";R:2;s:4:"0000";d:0;s:4:"0000";a:9:{s:4:"0000";';
+var_dump(unserialize($poc));
+?>
+--EXPECTF--
+Notice: unserialize(): Error at offset 43 of 145 bytes in %s on line %d
+bool(false)
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c
index 21a810bb01..2c5ea75adb 100644
--- a/ext/standard/var_unserializer.c
+++ b/ext/standard/var_unserializer.c
@@ -1,4 +1,4 @@
-/* Generated by re2c 0.14.3 */
+/* Generated by re2c 0.16 */
#line 1 "ext/standard/var_unserializer.re"
/*
+----------------------------------------------------------------------+
@@ -491,16 +491,7 @@ string_key:
return 0;
}
- if (UNEXPECTED(Z_ISUNDEF_P(data))) {
- if (Z_TYPE(key) == IS_LONG) {
- zend_hash_index_del(ht, Z_LVAL(key));
- } else {
- zend_hash_del_ind(ht, Z_STR(key));
- }
- } else {
- var_push_dtor(var_hash, data);
- }
-
+ var_push_dtor(var_hash, data);
zval_ptr_dtor(&key);
if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
@@ -661,7 +652,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
start = cursor;
-#line 665 "ext/standard/var_unserializer.c"
+#line 656 "ext/standard/var_unserializer.c"
{
YYCTYPE yych;
static const unsigned char yybm[] = {
@@ -698,105 +689,456 @@ 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 yy13;
+ case 'O': goto yy4;
case 'N': goto yy5;
- case 'R': goto yy2;
- case 'S': goto yy10;
- case 'a': goto yy11;
- case 'b': goto yy6;
- case 'd': goto yy8;
- case 'i': goto yy7;
+ case 'R': goto yy6;
+ case 'S': goto yy7;
+ case 'a': goto yy8;
+ case 'b': goto yy9;
+ case 'd': goto yy10;
+ case 'i': goto yy11;
case 'o': goto yy12;
- case 'r': goto yy4;
- case 's': goto yy9;
- case '}': goto yy14;
- default: goto yy16;
+ case 'r': goto yy13;
+ case 's': goto yy14;
+ case '}': goto yy15;
+ default: goto yy2;
}
yy2:
- yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy88;
+ ++YYCURSOR;
yy3:
-#line 1054 "ext/standard/var_unserializer.re"
+#line 1043 "ext/standard/var_unserializer.re"
{ return 0; }
-#line 727 "ext/standard/var_unserializer.c"
+#line 716 "ext/standard/var_unserializer.c"
yy4:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy83;
+ if (yych == ':') goto yy17;
goto yy3;
yy5:
yych = *++YYCURSOR;
- if (yych == ';') goto yy81;
+ if (yych == ';') goto yy19;
goto yy3;
yy6:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy77;
+ if (yych == ':') goto yy21;
goto yy3;
yy7:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy71;
+ if (yych == ':') goto yy22;
goto yy3;
yy8:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy48;
+ if (yych == ':') goto yy23;
goto yy3;
yy9:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy42;
+ if (yych == ':') goto yy24;
goto yy3;
yy10:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy36;
+ if (yych == ':') goto yy25;
goto yy3;
yy11:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy30;
+ if (yych == ':') goto yy26;
goto yy3;
yy12:
yych = *(YYMARKER = ++YYCURSOR);
- if (yych == ':') goto yy24;
+ 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 1048 "ext/standard/var_unserializer.re"
+#line 1037 "ext/standard/var_unserializer.re"
{
/* this is the case where we have less data than planned */
php_error_docref(NULL, E_NOTICE, "Unexpected end of serialized data");
return 0; /* not sure if it should be 0 or 1 here? */
}
-#line 776 "ext/standard/var_unserializer.c"
-yy16:
- yych = *++YYCURSOR;
- goto yy3;
+#line 769 "ext/standard/var_unserializer.c"
yy17:
yych = *++YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy19;
+ goto yy30;
}
yy18:
YYCURSOR = YYMARKER;
goto yy3;
yy19:
++YYCURSOR;
+#line 709 "ext/standard/var_unserializer.re"
+ {
+ *p = YYCURSOR;
+ ZVAL_NULL(rval);
+ return 1;
+}
+#line 786 "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 (yych <= '/') goto yy18;
+ if (yych <= '1') goto yy38;
+ goto yy18;
+yy25:
+ yych = *++YYCURSOR;
+ if (yych <= '/') {
+ if (yych <= ',') {
+ if (yych == '+') goto yy39;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy40;
+ if (yych <= '.') goto yy41;
+ goto yy18;
+ }
+ } else {
+ if (yych <= 'I') {
+ if (yych <= '9') goto yy42;
+ if (yych <= 'H') goto yy18;
+ goto yy44;
+ } else {
+ if (yych == 'N') goto yy45;
+ goto yy18;
+ }
+ }
+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;
+ }
+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:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy53;
+ goto yy18;
+yy30:
+ ++YYCURSOR;
if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
yych = *YYCURSOR;
if (yybm[0+yych] & 128) {
- goto yy19;
+ goto yy30;
}
if (yych <= '/') goto yy18;
- 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:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy34;
+ if (yych <= ':') goto yy58;
+ goto yy18;
+yy36:
+ ++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:
+ yych = *++YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy62;
+ goto yy18;
+yy42:
+ ++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;
+ }
+ }
+yy44:
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy67;
+ goto yy18;
+yy45:
+ yych = *++YYCURSOR;
+ if (yych == 'A') goto yy68;
+ goto yy18;
+yy46:
+ 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:
+ ++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:
+ ++YYCURSOR;
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
+ yych = *YYCURSOR;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy51;
+ if (yych == ';') goto yy72;
+ goto yy18;
+yy53:
+ ++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:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy75;
+ goto yy18;
+yy56:
+ ++YYCURSOR;
+#line 660 "ext/standard/var_unserializer.re"
+ {
+ zend_long id;
+
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ id = parse_uiv(start + 2) - 1;
+ if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
+ return 0;
+ }
+
+ if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
+ return 0;
+ }
+
+ if (Z_ISREF_P(rval_ref)) {
+ ZVAL_COPY(rval, rval_ref);
+ } else {
+ ZVAL_NEW_REF(rval_ref, rval_ref);
+ ZVAL_COPY(rval, rval_ref);
+ }
+
+ return 1;
+}
+#line 1010 "ext/standard/var_unserializer.c"
+yy58:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy77;
+ goto yy18;
+yy59:
+ yych = *++YYCURSOR;
+ if (yych == '{') goto yy79;
+ goto yy18;
+yy60:
+ ++YYCURSOR;
+#line 715 "ext/standard/var_unserializer.re"
+ {
+ *p = YYCURSOR;
+ ZVAL_BOOL(rval, parse_iv(start + 2));
+ return 1;
+}
+#line 1027 "ext/standard/var_unserializer.c"
+yy62:
+ ++YYCURSOR;
+ if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
+ yych = *YYCURSOR;
+ if (yych <= ';') {
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy62;
+ if (yych <= ':') goto yy18;
+ } else {
+ if (yych <= 'E') {
+ if (yych <= 'D') goto yy18;
+ goto yy66;
+ } else {
+ if (yych == 'e') goto yy66;
+ goto yy18;
+ }
+ }
+yy64:
+ ++YYCURSOR;
+#line 763 "ext/standard/var_unserializer.re"
+ {
+#if SIZEOF_ZEND_LONG == 4
+use_double:
+#endif
+ *p = YYCURSOR;
+ ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
+ return 1;
+}
+#line 1056 "ext/standard/var_unserializer.c"
+yy66:
yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
+ if (yych <= ',') {
+ if (yych == '+') goto yy81;
+ goto yy18;
+ } else {
+ if (yych <= '-') goto yy81;
+ if (yych <= '/') goto yy18;
+ if (yych <= '9') goto yy82;
+ goto yy18;
+ }
+yy67:
+ yych = *++YYCURSOR;
+ if (yych == 'F') goto yy84;
+ goto yy18;
+yy68:
+ yych = *++YYCURSOR;
+ if (yych == 'N') goto yy84;
+ goto yy18;
+yy69:
++YYCURSOR;
-#line 896 "ext/standard/var_unserializer.re"
+#line 721 "ext/standard/var_unserializer.re"
+ {
+#if SIZEOF_ZEND_LONG == 4
+ int digits = YYCURSOR - start - 3;
+
+ if (start[2] == '-' || start[2] == '+') {
+ digits--;
+ }
+
+ /* Use double for large zend_long values that were serialized on a 64-bit system */
+ if (digits >= MAX_LENGTH_OF_LONG - 1) {
+ if (digits == MAX_LENGTH_OF_LONG - 1) {
+ int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
+
+ if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
+ goto use_double;
+ }
+ } else {
+ goto use_double;
+ }
+ }
+#endif
+ *p = YYCURSOR;
+ ZVAL_LONG(rval, parse_iv(start + 2));
+ return 1;
+}
+#line 1104 "ext/standard/var_unserializer.c"
+yy71:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy85;
+ goto yy18;
+yy72:
+ ++YYCURSOR;
+#line 685 "ext/standard/var_unserializer.re"
+ {
+ zend_long id;
+
+ *p = YYCURSOR;
+ if (!var_hash) return 0;
+
+ id = parse_uiv(start + 2) - 1;
+ if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
+ return 0;
+ }
+
+ if (rval_ref == rval) {
+ return 0;
+ }
+
+ if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
+ return 0;
+ }
+
+ ZVAL_COPY(rval, rval_ref);
+
+ return 1;
+}
+#line 1135 "ext/standard/var_unserializer.c"
+yy74:
+ yych = *++YYCURSOR;
+ if (yych == '"') goto yy87;
+ goto yy18;
+yy75:
+ ++YYCURSOR;
+#line 885 "ext/standard/var_unserializer.re"
{
size_t len, len2, len3, maxlen;
zend_long elements;
@@ -948,48 +1290,47 @@ yy19:
return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
-#line 952 "ext/standard/var_unserializer.c"
-yy24:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy25:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy25;
- if (yych >= ';') goto yy18;
- yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
+#line 1294 "ext/standard/var_unserializer.c"
+yy77:
++YYCURSOR;
-#line 885 "ext/standard/var_unserializer.re"
+#line 810 "ext/standard/var_unserializer.re"
{
- zend_long elements;
- if (!var_hash) return 0;
+ size_t len, maxlen;
+ zend_string *str;
- elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
- if (elements < 0 || elements >= HT_MAX_SIZE) {
+ len = parse_uiv(start + 2);
+ maxlen = max - YYCURSOR;
+ if (maxlen < len) {
+ *p = start + 2;
return 0;
}
- return object_common2(UNSERIALIZE_PASSTHRU, elements);
+
+ if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) {
+ return 0;
+ }
+
+ if (*(YYCURSOR) != '"') {
+ zend_string_free(str);
+ *p = YYCURSOR;
+ return 0;
+ }
+
+ if (*(YYCURSOR + 1) != ';') {
+ efree(str);
+ *p = YYCURSOR + 1;
+ return 0;
+ }
+
+ YYCURSOR += 2;
+ *p = YYCURSOR;
+
+ ZVAL_STR(rval, str);
+ return 1;
}
-#line 978 "ext/standard/var_unserializer.c"
-yy30:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy31:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy31;
- if (yych >= ';') goto yy18;
- yych = *++YYCURSOR;
- if (yych != '{') goto yy18;
+#line 1331 "ext/standard/var_unserializer.c"
+yy79:
++YYCURSOR;
-#line 855 "ext/standard/var_unserializer.re"
+#line 844 "ext/standard/var_unserializer.re"
{
zend_long elements = parse_iv(start + 2);
/* use iv() not uiv() in order to check data range */
@@ -1019,71 +1360,40 @@ yy31:
return finish_nested_data(UNSERIALIZE_PASSTHRU);
}
-#line 1023 "ext/standard/var_unserializer.c"
-yy36:
+#line 1364 "ext/standard/var_unserializer.c"
+yy81:
yych = *++YYCURSOR;
if (yych <= '/') goto yy18;
if (yych >= ':') goto yy18;
-yy37:
+yy82:
++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
+ if (YYLIMIT <= YYCURSOR) YYFILL(1);
yych = *YYCURSOR;
if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy37;
- if (yych >= ';') goto yy18;
+ if (yych <= '9') goto yy82;
+ if (yych == ';') goto yy64;
+ goto yy18;
+yy84:
yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
+ if (yych == ';') goto yy89;
+ goto yy18;
+yy85:
++YYCURSOR;
-#line 821 "ext/standard/var_unserializer.re"
+#line 874 "ext/standard/var_unserializer.re"
{
- size_t len, maxlen;
- zend_string *str;
-
- len = parse_uiv(start + 2);
- maxlen = max - YYCURSOR;
- if (maxlen < len) {
- *p = start + 2;
- return 0;
- }
-
- if ((str = unserialize_str(&YYCURSOR, len, maxlen)) == NULL) {
- return 0;
- }
-
- if (*(YYCURSOR) != '"') {
- zend_string_free(str);
- *p = YYCURSOR;
- return 0;
- }
+ zend_long elements;
+ if (!var_hash) return 0;
- if (*(YYCURSOR + 1) != ';') {
- efree(str);
- *p = YYCURSOR + 1;
+ elements = object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR);
+ if (elements < 0 || elements >= HT_MAX_SIZE) {
return 0;
}
-
- YYCURSOR += 2;
- *p = YYCURSOR;
-
- ZVAL_STR(rval, str);
- return 1;
+ return object_common2(UNSERIALIZE_PASSTHRU, elements);
}
-#line 1072 "ext/standard/var_unserializer.c"
-yy42:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy43:
+#line 1394 "ext/standard/var_unserializer.c"
+yy87:
++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 2) YYFILL(2);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy43;
- if (yych >= ';') goto yy18;
- yych = *++YYCURSOR;
- if (yych != '"') goto yy18;
- ++YYCURSOR;
-#line 783 "ext/standard/var_unserializer.re"
+#line 772 "ext/standard/var_unserializer.re"
{
size_t len, maxlen;
char *str;
@@ -1121,152 +1431,10 @@ yy43:
}
return 1;
}
-#line 1125 "ext/standard/var_unserializer.c"
-yy48:
- yych = *++YYCURSOR;
- if (yych <= '/') {
- if (yych <= ',') {
- if (yych == '+') goto yy52;
- goto yy18;
- } else {
- if (yych <= '-') goto yy50;
- if (yych <= '.') goto yy55;
- goto yy18;
- }
- } else {
- if (yych <= 'I') {
- if (yych <= '9') goto yy53;
- if (yych <= 'H') goto yy18;
- goto yy51;
- } else {
- if (yych != 'N') goto yy18;
- }
- }
- yych = *++YYCURSOR;
- if (yych == 'A') goto yy70;
- goto yy18;
-yy50:
- yych = *++YYCURSOR;
- if (yych <= '/') {
- if (yych == '.') goto yy55;
- goto yy18;
- } else {
- if (yych <= '9') goto yy53;
- if (yych != 'I') goto yy18;
- }
-yy51:
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy66;
- goto yy18;
-yy52:
- yych = *++YYCURSOR;
- if (yych == '.') goto yy55;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy53:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
- yych = *YYCURSOR;
- if (yych <= ':') {
- if (yych <= '.') {
- if (yych <= '-') goto yy18;
- goto yy64;
- } else {
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy53;
- goto yy18;
- }
- } else {
- if (yych <= 'E') {
- if (yych <= ';') goto yy58;
- if (yych <= 'D') goto yy18;
- goto yy60;
- } else {
- if (yych == 'e') goto yy60;
- goto yy18;
- }
- }
-yy55:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy56:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
- yych = *YYCURSOR;
- if (yych <= ';') {
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy56;
- if (yych <= ':') goto yy18;
- } else {
- if (yych <= 'E') {
- if (yych <= 'D') goto yy18;
- goto yy60;
- } else {
- if (yych == 'e') goto yy60;
- goto yy18;
- }
- }
-yy58:
- ++YYCURSOR;
-#line 774 "ext/standard/var_unserializer.re"
- {
-#if SIZEOF_ZEND_LONG == 4
-use_double:
-#endif
- *p = YYCURSOR;
- ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL));
- return 1;
-}
-#line 1222 "ext/standard/var_unserializer.c"
-yy60:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy61;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy62;
- goto yy18;
- }
-yy61:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy62:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy62;
- if (yych == ';') goto yy58;
- goto yy18;
-yy64:
- ++YYCURSOR;
- if ((YYLIMIT - YYCURSOR) < 3) YYFILL(3);
- yych = *YYCURSOR;
- if (yych <= ';') {
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy64;
- if (yych <= ':') goto yy18;
- goto yy58;
- } else {
- if (yych <= 'E') {
- if (yych <= 'D') goto yy18;
- goto yy60;
- } else {
- if (yych == 'e') goto yy60;
- goto yy18;
- }
- }
-yy66:
- yych = *++YYCURSOR;
- if (yych != 'F') goto yy18;
-yy67:
- yych = *++YYCURSOR;
- if (yych != ';') goto yy18;
+#line 1435 "ext/standard/var_unserializer.c"
+yy89:
++YYCURSOR;
-#line 758 "ext/standard/var_unserializer.re"
+#line 747 "ext/standard/var_unserializer.re"
{
*p = YYCURSOR;
@@ -1282,162 +1450,9 @@ yy67:
return 1;
}
-#line 1286 "ext/standard/var_unserializer.c"
-yy70:
- yych = *++YYCURSOR;
- if (yych == 'N') goto yy67;
- goto yy18;
-yy71:
- yych = *++YYCURSOR;
- if (yych <= ',') {
- if (yych != '+') goto yy18;
- } else {
- if (yych <= '-') goto yy72;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy73;
- goto yy18;
- }
-yy72:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy73:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy73;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 732 "ext/standard/var_unserializer.re"
- {
-#if SIZEOF_ZEND_LONG == 4
- int digits = YYCURSOR - start - 3;
-
- if (start[2] == '-' || start[2] == '+') {
- digits--;
- }
-
- /* Use double for large zend_long values that were serialized on a 64-bit system */
- if (digits >= MAX_LENGTH_OF_LONG - 1) {
- if (digits == MAX_LENGTH_OF_LONG - 1) {
- int cmp = strncmp((char*)YYCURSOR - MAX_LENGTH_OF_LONG, long_min_digits, MAX_LENGTH_OF_LONG - 1);
-
- if (!(cmp < 0 || (cmp == 0 && start[2] == '-'))) {
- goto use_double;
- }
- } else {
- goto use_double;
- }
- }
-#endif
- *p = YYCURSOR;
- ZVAL_LONG(rval, parse_iv(start + 2));
- return 1;
-}
-#line 1339 "ext/standard/var_unserializer.c"
-yy77:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= '2') goto yy18;
- yych = *++YYCURSOR;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 726 "ext/standard/var_unserializer.re"
- {
- *p = YYCURSOR;
- ZVAL_BOOL(rval, parse_iv(start + 2));
- return 1;
-}
-#line 1353 "ext/standard/var_unserializer.c"
-yy81:
- ++YYCURSOR;
-#line 720 "ext/standard/var_unserializer.re"
- {
- *p = YYCURSOR;
- ZVAL_NULL(rval);
- return 1;
-}
-#line 1362 "ext/standard/var_unserializer.c"
-yy83:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy84:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy84;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 695 "ext/standard/var_unserializer.re"
- {
- zend_long id;
-
- *p = YYCURSOR;
- if (!var_hash) return 0;
-
- id = parse_uiv(start + 2) - 1;
- if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
- return 0;
- }
-
- if (rval_ref == rval) {
- return 0;
- }
-
- if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
- ZVAL_UNDEF(rval);
- return 1;
- }
-
- ZVAL_COPY(rval, rval_ref);
-
- return 1;
-}
-#line 1400 "ext/standard/var_unserializer.c"
-yy88:
- yych = *++YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych >= ':') goto yy18;
-yy89:
- ++YYCURSOR;
- if (YYLIMIT <= YYCURSOR) YYFILL(1);
- yych = *YYCURSOR;
- if (yych <= '/') goto yy18;
- if (yych <= '9') goto yy89;
- if (yych != ';') goto yy18;
- ++YYCURSOR;
-#line 669 "ext/standard/var_unserializer.re"
- {
- zend_long id;
-
- *p = YYCURSOR;
- if (!var_hash) return 0;
-
- id = parse_uiv(start + 2) - 1;
- if (id == -1 || (rval_ref = var_access(var_hash, id)) == NULL) {
- return 0;
- }
-
- zval_ptr_dtor(rval);
- if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
- ZVAL_UNDEF(rval);
- return 1;
- }
- if (Z_ISREF_P(rval_ref)) {
- ZVAL_COPY(rval, rval_ref);
- } else {
- ZVAL_NEW_REF(rval_ref, rval_ref);
- ZVAL_COPY(rval, rval_ref);
- }
-
- return 1;
-}
-#line 1439 "ext/standard/var_unserializer.c"
+#line 1454 "ext/standard/var_unserializer.c"
}
-#line 1056 "ext/standard/var_unserializer.re"
+#line 1045 "ext/standard/var_unserializer.re"
return 0;
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re
index 1285d41b47..de0db395e3 100644
--- a/ext/standard/var_unserializer.re
+++ b/ext/standard/var_unserializer.re
@@ -495,16 +495,7 @@ string_key:
return 0;
}
- if (UNEXPECTED(Z_ISUNDEF_P(data))) {
- if (Z_TYPE(key) == IS_LONG) {
- zend_hash_index_del(ht, Z_LVAL(key));
- } else {
- zend_hash_del_ind(ht, Z_STR(key));
- }
- } else {
- var_push_dtor(var_hash, data);
- }
-
+ var_push_dtor(var_hash, data);
zval_ptr_dtor(&key);
if (elements && *(*p-1) != ';' && *(*p-1) != '}') {
@@ -677,11 +668,10 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
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;
+ return 0;
}
+
if (Z_ISREF_P(rval_ref)) {
ZVAL_COPY(rval, rval_ref);
} else {
@@ -708,8 +698,7 @@ static int php_var_unserialize_internal(UNSERIALIZE_PARAMETER)
}
if (Z_ISUNDEF_P(rval_ref) || (Z_ISREF_P(rval_ref) && Z_ISUNDEF_P(Z_REFVAL_P(rval_ref)))) {
- ZVAL_UNDEF(rval);
- return 1;
+ return 0;
}
ZVAL_COPY(rval, rval_ref);