From 643c61277f9aa6f171a70bd7fc7a4c1d7af4710f Mon Sep 17 00:00:00 2001 From: Marcus Boerger Date: Fri, 24 Sep 2004 22:05:14 +0000 Subject: [PATCH] - MFH unserialize fixes # .re first --- ext/standard/var_unserializer.re | 92 +++++++++++++++++++++++++------- 1 file changed, 73 insertions(+), 19 deletions(-) diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 6ae7424b77..c57de7ae03 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -119,7 +119,7 @@ any = [\000-\277]; -static inline int parse_iv2(const char *p, const char **q) +static inline int parse_iv2(const unsigned char *p, const unsigned char **q) { char cursor; int result = 0; @@ -134,7 +134,7 @@ static inline int parse_iv2(const char *p, const char **q) } while (1) { - cursor = *p; + cursor = (char)*p; if (cursor >= '0' && cursor <= '9') { result = result * 10 + cursor - '0'; } else { @@ -147,12 +147,34 @@ static inline int parse_iv2(const char *p, const char **q) return result; } -static inline int parse_iv(const char *p) +static inline int parse_iv(const unsigned char *p) { return parse_iv2(p, NULL); } -#define UNSERIALIZE_PARAMETER zval **rval, const char **p, const char *max, php_unserialize_data_t *var_hash TSRMLS_DC +/* no need to check for length - re2c already did */ +static inline size_t parse_uiv(const unsigned char *p) +{ + unsigned char cursor; + size_t result = 0; + + if (*p == '+') { + p++; + } + + while (1) { + cursor = *p; + if (cursor >= '0' && cursor <= '9') { + result = result * 10 + (size_t)(cursor - (unsigned char)'0'); + } else { + break; + } + 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 static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int elements) @@ -168,6 +190,12 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int return 0; } + if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) { + zval_dtor(key); + FREE_ZVAL(key); + return 0; + } + ALLOC_INIT_ZVAL(data); if (!php_var_unserialize(&data, p, max, var_hash TSRMLS_CC)) { @@ -185,11 +213,15 @@ static inline int process_nested_data(UNSERIALIZE_PARAMETER, HashTable *ht, int case IS_STRING: zend_hash_update(ht, Z_STRVAL_P(key), Z_STRLEN_P(key) + 1, &data, sizeof(data), NULL); break; - } zval_dtor(key); FREE_ZVAL(key); + + if (elements && *(*p-1) != ';' && *(*p-1) != '}') { + (*p)--; + return 0; + } } return 1; @@ -306,7 +338,7 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) return 1; } -"b:" iv ";" { +"b:" [01] ";" { *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); @@ -345,22 +377,30 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) } "s:" uiv ":" ["] { - int len; + size_t len, maxlen; char *str; - len = parse_iv(start + 2); + len = parse_uiv(start + 2); + maxlen = max - YYCURSOR; + if (maxlen < len) { + *p = start + 2; + return 0; + } + + str = (char*)YYCURSOR; + + YYCURSOR += len; - if (len == 0) { - str = empty_string; - } else { - str = estrndup(YYCURSOR, len); + if (*(YYCURSOR) != '"') { + *p = YYCURSOR; + return 0; } - YYCURSOR += len + 2; + YYCURSOR += 2; *p = YYCURSOR; INIT_PZVAL(*rval); - ZVAL_STRINGL(*rval, str, len, 0); + ZVAL_STRINGL(*rval, str, len, 1); return 1; } @@ -391,9 +431,8 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) } "O:" uiv ":" ["] { - int len; + size_t len, len2, maxlen; int elements; - int len2; char *class_name; zend_class_entry *ce; zend_class_entry **pce; @@ -405,13 +444,28 @@ PHPAPI int php_var_unserialize(UNSERIALIZE_PARAMETER) zval *arg_func_name; INIT_PZVAL(*rval); - len2 = len = parse_iv(start + 2); - if (len == 0) + len2 = len = parse_uiv(start + 2); + maxlen = max - YYCURSOR; + if (maxlen < len || len == 0) { + *p = start + 2; return 0; + } + + class_name = (char*)YYCURSOR; - class_name = estrndup(YYCURSOR, len); YYCURSOR += len; + if (*(YYCURSOR) != '"') { + *p = YYCURSOR; + return 0; + } + if (*(YYCURSOR+1) != ':') { + *p = YYCURSOR+1; + return 0; + } + + class_name = estrndup(class_name, len); + do { /* Try to find class directly */ if (zend_lookup_class(class_name, len2, &pce TSRMLS_CC) == SUCCESS) { -- 2.40.0