Skip to content

Instantly share code, notes, and snippets.

/72785.diff Secret

Created August 14, 2016 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/360b34c65bcb11f917bbef4ba29acfd3 to your computer and use it in GitHub Desktop.
Save anonymous/360b34c65bcb11f917bbef4ba29acfd3 to your computer and use it in GitHub Desktop.
Patch for 72785
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