helly Fri Sep 24 18:05:16 2004 EDT
Modified files: (Branch: PHP_5_0)
/php-src/ext/standard var_unserializer.re
Log:
- MFH unserialize fixes
# .re first
http://cvs.php.net/diff.php/php-src/ext/standard/var_unserializer.re?r1=1.27&r2=1.27.2.1&ty=u
Index: php-src/ext/standard/var_unserializer.re
diff -u php-src/ext/standard/var_unserializer.re:1.27
php-src/ext/standard/var_unserializer.re:1.27.2.1
--- php-src/ext/standard/var_unserializer.re:1.27 Fri Mar 26 19:50:39 2004
+++ php-src/ext/standard/var_unserializer.re Fri Sep 24 18:05:14 2004
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: var_unserializer.re,v 1.27 2004/03/27 00:50:39 helly Exp $ */
+/* $Id: var_unserializer.re,v 1.27.2.1 2004/09/24 22:05:14 helly Exp $ */
#include "php.h"
#include "ext/standard/php_var.h"
@@ -119,7 +119,7 @@
-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 @@
}
while (1) {
- cursor = *p;
+ cursor = (char)*p;
if (cursor >= '0' && cursor <= '9') {
result = result * 10 + cursor - '0';
} else {
@@ -147,12 +147,34 @@
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 @@
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 @@
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 @@
return 1;
}
-"b:" iv ";" {
+"b:" [01] ";" {
*p = YYCURSOR;
INIT_PZVAL(*rval);
ZVAL_BOOL(*rval, parse_iv(start + 2));
@@ -345,22 +377,30 @@
}
"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 @@
}
"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,12 +444,27 @@
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 */
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php