-
-
Save anonymous/360b34c65bcb11f917bbef4ba29acfd3 to your computer and use it in GitHub Desktop.
Patch for 72785
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
commit 06b1cee438c82034d56c5239998538fac0dea544 | |
Author: Stanislav Malyshev <stas@php.net> | |
Date: Sat Aug 13 18:18:55 2016 -0700 | |
Fix for #72785 - keep allows classes list around | |
diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h | |
index 4afefbe..91a9784 100644 | |
--- a/ext/standard/php_var.h | |
+++ b/ext/standard/php_var.h | |
@@ -48,6 +48,7 @@ struct php_unserialize_data { | |
void *last; | |
void *first_dtor; | |
void *last_dtor; | |
+ HashTable *class_hash; | |
}; | |
typedef struct php_serialize_data *php_serialize_data_t; | |
diff --git a/ext/standard/var.c b/ext/standard/var.c | |
index 472cd62..5f22982 100644 | |
--- a/ext/standard/var.c | |
+++ b/ext/standard/var.c | |
@@ -1050,6 +1050,10 @@ PHP_FUNCTION(unserialize) | |
PHP_VAR_UNSERIALIZE_INIT(var_hash); | |
if (options != NULL) { | |
classes = zend_hash_str_find(Z_ARRVAL_P(options), "allowed_classes", sizeof("allowed_classes")-1); | |
+ if (classes && Z_TYPE_P(classes) != IS_ARRAY && Z_TYPE_P(classes) != IS_TRUE && Z_TYPE_P(classes) != IS_FALSE) { | |
+ php_error_docref(NULL, E_WARNING, "allowed_classes option should be array or boolean"); | |
+ RETURN_FALSE; | |
+ } | |
if (classes && (Z_TYPE_P(classes) == IS_ARRAY || !zend_is_true(classes))) { | |
ALLOC_HASHTABLE(class_hash); | |
zend_hash_init(class_hash, (Z_TYPE_P(classes) == IS_ARRAY)?zend_hash_num_elements(Z_ARRVAL_P(classes)):0, NULL, NULL, 0); | |
@@ -1067,6 +1071,10 @@ PHP_FUNCTION(unserialize) | |
} | |
} | |
+ if (!var_hash->class_hash) { | |
+ var_hash->class_hash = class_hash; | |
+ } | |
+ | |
if (!php_var_unserialize_ex(return_value, &p, p + buf_len, &var_hash, class_hash)) { | |
PHP_VAR_UNSERIALIZE_DESTROY(var_hash); | |
if (class_hash) { | |
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c | |
index 3fc074d..a599184 100644 | |
--- a/ext/standard/var_unserializer.c | |
+++ b/ext/standard/var_unserializer.c | |
@@ -1,4 +1,4 @@ | |
-/* Generated by re2c 0.13.5 */ | |
+/* Generated by re2c 0.13.7.5 */ | |
#line 1 "ext/standard/var_unserializer.re" | |
/* | |
+----------------------------------------------------------------------+ | |
@@ -491,6 +491,9 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements) | |
PHPAPI int php_var_unserialize(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash) | |
{ | |
HashTable *classes = NULL; | |
+ if (BG(unserialize).level > 1) { | |
+ classes = (*var_hash)->class_hash; | |
+ } | |
return php_var_unserialize_ex(UNSERIALIZE_PASSTHRU); | |
} | |
@@ -514,7 +517,7 @@ PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) | |
start = cursor; | |
-#line 518 "ext/standard/var_unserializer.c" | |
+#line 521 "ext/standard/var_unserializer.c" | |
{ | |
YYCTYPE yych; | |
static const unsigned char yybm[] = { | |
@@ -574,9 +577,9 @@ yy2: | |
yych = *(YYMARKER = ++YYCURSOR); | |
if (yych == ':') goto yy95; | |
yy3: | |
-#line 884 "ext/standard/var_unserializer.re" | |
+#line 887 "ext/standard/var_unserializer.re" | |
{ return 0; } | |
-#line 580 "ext/standard/var_unserializer.c" | |
+#line 583 "ext/standard/var_unserializer.c" | |
yy4: | |
yych = *(YYMARKER = ++YYCURSOR); | |
if (yych == ':') goto yy89; | |
@@ -619,13 +622,13 @@ yy13: | |
goto yy3; | |
yy14: | |
++YYCURSOR; | |
-#line 878 "ext/standard/var_unserializer.re" | |
+#line 881 "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 629 "ext/standard/var_unserializer.c" | |
+#line 632 "ext/standard/var_unserializer.c" | |
yy16: | |
yych = *++YYCURSOR; | |
goto yy3; | |
@@ -651,11 +654,12 @@ yy20: | |
if (yybm[0+yych] & 128) { | |
goto yy20; | |
} | |
- if (yych != ':') goto yy18; | |
+ if (yych <= '/') goto yy18; | |
+ if (yych >= ';') goto yy18; | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 733 "ext/standard/var_unserializer.re" | |
+#line 736 "ext/standard/var_unserializer.re" | |
{ | |
size_t len, len2, len3, maxlen; | |
zend_long elements; | |
@@ -800,7 +804,7 @@ yy20: | |
return object_common2(UNSERIALIZE_PASSTHRU, elements); | |
} | |
-#line 804 "ext/standard/var_unserializer.c" | |
+#line 808 "ext/standard/var_unserializer.c" | |
yy25: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -825,14 +829,14 @@ yy27: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 726 "ext/standard/var_unserializer.re" | |
+#line 729 "ext/standard/var_unserializer.re" | |
{ | |
if (!var_hash) return 0; | |
return object_common2(UNSERIALIZE_PASSTHRU, | |
object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); | |
} | |
-#line 836 "ext/standard/var_unserializer.c" | |
+#line 840 "ext/standard/var_unserializer.c" | |
yy32: | |
yych = *++YYCURSOR; | |
if (yych == '+') goto yy33; | |
@@ -853,7 +857,7 @@ yy34: | |
yych = *++YYCURSOR; | |
if (yych != '{') goto yy18; | |
++YYCURSOR; | |
-#line 702 "ext/standard/var_unserializer.re" | |
+#line 705 "ext/standard/var_unserializer.re" | |
{ | |
zend_long elements = parse_iv(start + 2); | |
/* use iv() not uiv() in order to check data range */ | |
@@ -877,7 +881,7 @@ yy34: | |
return finish_nested_data(UNSERIALIZE_PASSTHRU); | |
} | |
-#line 881 "ext/standard/var_unserializer.c" | |
+#line 885 "ext/standard/var_unserializer.c" | |
yy39: | |
yych = *++YYCURSOR; | |
if (yych == '+') goto yy40; | |
@@ -898,7 +902,7 @@ yy41: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 668 "ext/standard/var_unserializer.re" | |
+#line 671 "ext/standard/var_unserializer.re" | |
{ | |
size_t len, maxlen; | |
zend_string *str; | |
@@ -932,7 +936,7 @@ yy41: | |
ZVAL_STR(rval, str); | |
return 1; | |
} | |
-#line 936 "ext/standard/var_unserializer.c" | |
+#line 940 "ext/standard/var_unserializer.c" | |
yy46: | |
yych = *++YYCURSOR; | |
if (yych == '+') goto yy47; | |
@@ -953,7 +957,7 @@ yy48: | |
yych = *++YYCURSOR; | |
if (yych != '"') goto yy18; | |
++YYCURSOR; | |
-#line 636 "ext/standard/var_unserializer.re" | |
+#line 639 "ext/standard/var_unserializer.re" | |
{ | |
size_t len, maxlen; | |
char *str; | |
@@ -985,7 +989,7 @@ yy48: | |
ZVAL_STRINGL(rval, str, len); | |
return 1; | |
} | |
-#line 989 "ext/standard/var_unserializer.c" | |
+#line 993 "ext/standard/var_unserializer.c" | |
yy53: | |
yych = *++YYCURSOR; | |
if (yych <= '/') { | |
@@ -1073,7 +1077,7 @@ yy61: | |
} | |
yy63: | |
++YYCURSOR; | |
-#line 627 "ext/standard/var_unserializer.re" | |
+#line 630 "ext/standard/var_unserializer.re" | |
{ | |
#if SIZEOF_ZEND_LONG == 4 | |
use_double: | |
@@ -1082,7 +1086,7 @@ use_double: | |
ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); | |
return 1; | |
} | |
-#line 1086 "ext/standard/var_unserializer.c" | |
+#line 1090 "ext/standard/var_unserializer.c" | |
yy65: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -1141,7 +1145,7 @@ yy73: | |
yych = *++YYCURSOR; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 611 "ext/standard/var_unserializer.re" | |
+#line 614 "ext/standard/var_unserializer.re" | |
{ | |
*p = YYCURSOR; | |
@@ -1157,7 +1161,7 @@ yy73: | |
return 1; | |
} | |
-#line 1161 "ext/standard/var_unserializer.c" | |
+#line 1165 "ext/standard/var_unserializer.c" | |
yy76: | |
yych = *++YYCURSOR; | |
if (yych == 'N') goto yy73; | |
@@ -1184,7 +1188,7 @@ yy79: | |
if (yych <= '9') goto yy79; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 585 "ext/standard/var_unserializer.re" | |
+#line 588 "ext/standard/var_unserializer.re" | |
{ | |
#if SIZEOF_ZEND_LONG == 4 | |
int digits = YYCURSOR - start - 3; | |
@@ -1210,7 +1214,7 @@ yy79: | |
ZVAL_LONG(rval, parse_iv(start + 2)); | |
return 1; | |
} | |
-#line 1214 "ext/standard/var_unserializer.c" | |
+#line 1218 "ext/standard/var_unserializer.c" | |
yy83: | |
yych = *++YYCURSOR; | |
if (yych <= '/') goto yy18; | |
@@ -1218,22 +1222,22 @@ yy83: | |
yych = *++YYCURSOR; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 579 "ext/standard/var_unserializer.re" | |
+#line 582 "ext/standard/var_unserializer.re" | |
{ | |
*p = YYCURSOR; | |
ZVAL_BOOL(rval, parse_iv(start + 2)); | |
return 1; | |
} | |
-#line 1228 "ext/standard/var_unserializer.c" | |
+#line 1232 "ext/standard/var_unserializer.c" | |
yy87: | |
++YYCURSOR; | |
-#line 573 "ext/standard/var_unserializer.re" | |
+#line 576 "ext/standard/var_unserializer.re" | |
{ | |
*p = YYCURSOR; | |
ZVAL_NULL(rval); | |
return 1; | |
} | |
-#line 1237 "ext/standard/var_unserializer.c" | |
+#line 1241 "ext/standard/var_unserializer.c" | |
yy89: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -1256,7 +1260,7 @@ yy91: | |
if (yych <= '9') goto yy91; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 548 "ext/standard/var_unserializer.re" | |
+#line 551 "ext/standard/var_unserializer.re" | |
{ | |
zend_long id; | |
@@ -1281,7 +1285,7 @@ yy91: | |
return 1; | |
} | |
-#line 1285 "ext/standard/var_unserializer.c" | |
+#line 1289 "ext/standard/var_unserializer.c" | |
yy95: | |
yych = *++YYCURSOR; | |
if (yych <= ',') { | |
@@ -1304,7 +1308,7 @@ yy97: | |
if (yych <= '9') goto yy97; | |
if (yych != ';') goto yy18; | |
++YYCURSOR; | |
-#line 522 "ext/standard/var_unserializer.re" | |
+#line 525 "ext/standard/var_unserializer.re" | |
{ | |
zend_long id; | |
@@ -1330,9 +1334,9 @@ yy97: | |
return 1; | |
} | |
-#line 1334 "ext/standard/var_unserializer.c" | |
+#line 1338 "ext/standard/var_unserializer.c" | |
} | |
-#line 886 "ext/standard/var_unserializer.re" | |
+#line 889 "ext/standard/var_unserializer.re" | |
return 0; | |
diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re | |
index 81cc26d..c6590fa 100644 | |
--- a/ext/standard/var_unserializer.re | |
+++ b/ext/standard/var_unserializer.re | |
@@ -495,6 +495,9 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements) | |
PHPAPI int php_var_unserialize(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash) | |
{ | |
HashTable *classes = NULL; | |
+ if (BG(unserialize).level > 1) { | |
+ classes = (*var_hash)->class_hash; | |
+ } | |
return php_var_unserialize_ex(UNSERIALIZE_PASSTHRU); | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment