diff options
Diffstat (limited to 'ext/standard/var_unserializer.c')
-rw-r--r-- | ext/standard/var_unserializer.c | 113 |
1 files changed, 74 insertions, 39 deletions
diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 9be2b0658a..d8b94e75cc 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" /* +----------------------------------------------------------------------+ @@ -226,6 +226,26 @@ static zend_string *unserialize_str(const unsigned char **p, size_t len, size_t return str; } +static inline int unserialize_allowed_class(zend_string *class_name, HashTable *classes) +{ + zend_string *lcname; + int res; + ALLOCA_FLAG(use_heap) + + if(classes == NULL) { + return 1; + } + if(!zend_hash_num_elements(classes)) { + return 0; + } + + STR_ALLOCA_ALLOC(lcname, class_name->len, use_heap); + zend_str_tolower_copy(lcname->val, class_name->val, class_name->len); + res = zend_hash_exists(classes, lcname); + STR_ALLOCA_FREE(lcname, use_heap); + return res; +} + #define YYFILL(n) do { } while (0) #define YYCTYPE unsigned char #define YYCURSOR cursor @@ -233,7 +253,7 @@ static zend_string *unserialize_str(const unsigned char **p, size_t len, size_t #define YYMARKER marker -#line 241 "ext/standard/var_unserializer.re" +#line 261 "ext/standard/var_unserializer.re" @@ -293,8 +313,8 @@ static inline size_t parse_uiv(const unsigned char *p) return result; } -#define UNSERIALIZE_PARAMETER zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC -#define UNSERIALIZE_PASSTHRU rval, p, max, var_hash TSRMLS_CC +#define UNSERIALIZE_PARAMETER zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash, HashTable *classes TSRMLS_DC +#define UNSERIALIZE_PASSTHRU rval, p, max, var_hash, classes TSRMLS_CC static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend_long elements, int objprops) { @@ -302,7 +322,8 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend zval key, *data, d, *old_data; ZVAL_UNDEF(&key); - if (!php_var_unserialize(&key, p, max, NULL TSRMLS_CC)) { + + if (!php_var_unserialize_ex(&key, p, max, NULL, classes TSRMLS_CC)) { zval_dtor(&key); return 0; } @@ -354,7 +375,7 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, zend zval_dtor(&key); - if (!php_var_unserialize(data, p, max, var_hash TSRMLS_CC)) { + if (!php_var_unserialize_ex(data, p, max, var_hash, classes TSRMLS_CC)) { return 0; } @@ -462,7 +483,14 @@ static inline int object_common2(UNSERIALIZE_PARAMETER, zend_long elements) # pragma optimize("", on) #endif -PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) +PHPAPI int php_var_unserialize(zval *rval, const unsigned char **p, const unsigned char *max, php_unserialize_data_t *var_hash TSRMLS_DC) +{ + HashTable *classes = NULL; + return php_var_unserialize_ex(UNSERIALIZE_PASSTHRU); +} + + +PHPAPI int php_var_unserialize_ex(UNSERIALIZE_PARAMETER) { const unsigned char *cursor, *limit, *marker, *start; zval *rval_ref; @@ -481,7 +509,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) start = cursor; -#line 485 "ext/standard/var_unserializer.c" +#line 513 "ext/standard/var_unserializer.c" { YYCTYPE yych; static const unsigned char yybm[] = { @@ -541,9 +569,9 @@ yy2: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy95; yy3: -#line 826 "ext/standard/var_unserializer.re" +#line 860 "ext/standard/var_unserializer.re" { return 0; } -#line 547 "ext/standard/var_unserializer.c" +#line 575 "ext/standard/var_unserializer.c" yy4: yych = *(YYMARKER = ++YYCURSOR); if (yych == ':') goto yy89; @@ -586,13 +614,13 @@ yy13: goto yy3; yy14: ++YYCURSOR; -#line 820 "ext/standard/var_unserializer.re" +#line 854 "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 596 "ext/standard/var_unserializer.c" +#line 624 "ext/standard/var_unserializer.c" yy16: yych = *++YYCURSOR; goto yy3; @@ -618,11 +646,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 681 "ext/standard/var_unserializer.re" +#line 709 "ext/standard/var_unserializer.re" { size_t len, len2, len3, maxlen; zend_long elements; @@ -672,6 +701,12 @@ yy20: class_name = zend_string_init(str, len, 0); do { + if(!unserialize_allowed_class(class_name, classes)) { + incomplete_class = 1; + ce = PHP_IC_ENTRY; + break; + } + /* Try to find class directly */ BG(serialize_lock)++; ce = zend_lookup_class(class_name TSRMLS_CC); @@ -761,7 +796,7 @@ yy20: return object_common2(UNSERIALIZE_PASSTHRU, elements); } -#line 765 "ext/standard/var_unserializer.c" +#line 800 "ext/standard/var_unserializer.c" yy25: yych = *++YYCURSOR; if (yych <= ',') { @@ -786,7 +821,7 @@ yy27: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 673 "ext/standard/var_unserializer.re" +#line 701 "ext/standard/var_unserializer.re" { //??? INIT_PZVAL(rval); @@ -794,7 +829,7 @@ yy27: return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } -#line 798 "ext/standard/var_unserializer.c" +#line 833 "ext/standard/var_unserializer.c" yy32: yych = *++YYCURSOR; if (yych == '+') goto yy33; @@ -815,7 +850,7 @@ yy34: yych = *++YYCURSOR; if (yych != '{') goto yy18; ++YYCURSOR; -#line 652 "ext/standard/var_unserializer.re" +#line 680 "ext/standard/var_unserializer.re" { zend_long elements = parse_iv(start + 2); /* use iv() not uiv() in order to check data range */ @@ -826,7 +861,7 @@ yy34: } array_init_size(rval, elements); -//??? we can't convert from packed to hash during unserialization, becaue +//??? we can't convert from packed to hash during unserialization, because //??? reference to some zvals might be keept in var_hash (to support references) zend_hash_real_init(Z_ARRVAL_P(rval), 0); @@ -836,7 +871,7 @@ yy34: return finish_nested_data(UNSERIALIZE_PASSTHRU); } -#line 840 "ext/standard/var_unserializer.c" +#line 875 "ext/standard/var_unserializer.c" yy39: yych = *++YYCURSOR; if (yych == '+') goto yy40; @@ -857,7 +892,7 @@ yy41: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 624 "ext/standard/var_unserializer.re" +#line 652 "ext/standard/var_unserializer.re" { size_t len, maxlen; zend_string *str; @@ -885,7 +920,7 @@ yy41: ZVAL_STR(rval, str); return 1; } -#line 889 "ext/standard/var_unserializer.c" +#line 924 "ext/standard/var_unserializer.c" yy46: yych = *++YYCURSOR; if (yych == '+') goto yy47; @@ -906,7 +941,7 @@ yy48: yych = *++YYCURSOR; if (yych != '"') goto yy18; ++YYCURSOR; -#line 597 "ext/standard/var_unserializer.re" +#line 625 "ext/standard/var_unserializer.re" { size_t len, maxlen; char *str; @@ -933,7 +968,7 @@ yy48: ZVAL_STRINGL(rval, str, len); return 1; } -#line 937 "ext/standard/var_unserializer.c" +#line 972 "ext/standard/var_unserializer.c" yy53: yych = *++YYCURSOR; if (yych <= '/') { @@ -1021,7 +1056,7 @@ yy61: } yy63: ++YYCURSOR; -#line 588 "ext/standard/var_unserializer.re" +#line 616 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 use_double: @@ -1030,7 +1065,7 @@ use_double: ZVAL_DOUBLE(rval, zend_strtod((const char *)start + 2, NULL)); return 1; } -#line 1034 "ext/standard/var_unserializer.c" +#line 1069 "ext/standard/var_unserializer.c" yy65: yych = *++YYCURSOR; if (yych <= ',') { @@ -1089,7 +1124,7 @@ yy73: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 572 "ext/standard/var_unserializer.re" +#line 600 "ext/standard/var_unserializer.re" { *p = YYCURSOR; @@ -1105,7 +1140,7 @@ yy73: return 1; } -#line 1109 "ext/standard/var_unserializer.c" +#line 1144 "ext/standard/var_unserializer.c" yy76: yych = *++YYCURSOR; if (yych == 'N') goto yy73; @@ -1132,7 +1167,7 @@ yy79: if (yych <= '9') goto yy79; if (yych != ';') goto yy18; ++YYCURSOR; -#line 546 "ext/standard/var_unserializer.re" +#line 574 "ext/standard/var_unserializer.re" { #if SIZEOF_ZEND_LONG == 4 int digits = YYCURSOR - start - 3; @@ -1158,7 +1193,7 @@ yy79: ZVAL_LONG(rval, parse_iv(start + 2)); return 1; } -#line 1162 "ext/standard/var_unserializer.c" +#line 1197 "ext/standard/var_unserializer.c" yy83: yych = *++YYCURSOR; if (yych <= '/') goto yy18; @@ -1166,22 +1201,22 @@ yy83: yych = *++YYCURSOR; if (yych != ';') goto yy18; ++YYCURSOR; -#line 540 "ext/standard/var_unserializer.re" +#line 568 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_BOOL(rval, parse_iv(start + 2)); return 1; } -#line 1176 "ext/standard/var_unserializer.c" +#line 1211 "ext/standard/var_unserializer.c" yy87: ++YYCURSOR; -#line 534 "ext/standard/var_unserializer.re" +#line 562 "ext/standard/var_unserializer.re" { *p = YYCURSOR; ZVAL_NULL(rval); return 1; } -#line 1185 "ext/standard/var_unserializer.c" +#line 1220 "ext/standard/var_unserializer.c" yy89: yych = *++YYCURSOR; if (yych <= ',') { @@ -1204,7 +1239,7 @@ yy91: if (yych <= '9') goto yy91; if (yych != ';') goto yy18; ++YYCURSOR; -#line 511 "ext/standard/var_unserializer.re" +#line 539 "ext/standard/var_unserializer.re" { zend_long id; @@ -1227,7 +1262,7 @@ yy91: return 1; } -#line 1231 "ext/standard/var_unserializer.c" +#line 1266 "ext/standard/var_unserializer.c" yy95: yych = *++YYCURSOR; if (yych <= ',') { @@ -1250,7 +1285,7 @@ yy97: if (yych <= '9') goto yy97; if (yych != ';') goto yy18; ++YYCURSOR; -#line 489 "ext/standard/var_unserializer.re" +#line 517 "ext/standard/var_unserializer.re" { zend_long id; @@ -1272,9 +1307,9 @@ yy97: return 1; } -#line 1276 "ext/standard/var_unserializer.c" +#line 1311 "ext/standard/var_unserializer.c" } -#line 828 "ext/standard/var_unserializer.re" +#line 862 "ext/standard/var_unserializer.re" return 0; |