php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login | |
Patch max_input_vars.patch for *General Issues Bug #60655Patch version 2012-01-05 05:02 UTC Return to Bug #60655 | Download this patchThis patch is obsolete Obsoleted by patches: This patch renders other patches obsolete Obsolete patches:
Developer: laruence@php.netIndex: trunk/ext/standard/php_var.h =================================================================== --- trunk/ext/standard/php_var.h (revision 321767) +++ trunk/ext/standard/php_var.h (working copy) @@ -95,9 +95,12 @@ @@ -95,9 +95,13 @@ } else { \ (var_hash_ptr) = (php_serialize_data_t)BG(unserialize).var_hash; \ ++BG(unserialize).level; \ - } \ + } \ + BG(unserialize).num_vars = 0; \ + BG(unserialize).max_vars = 0; \ } while (0) +#define PHP_VAR_UNSERIALIZE_MAX_VARS(max_vars) BG(unserialize).max_vars = max_vars; + + } s = p + 1; } if (s < e) { Index: branches/PHP_5_3/ext/standard/basic_functions.h =================================================================== --- branches/PHP_5_3/ext/standard/basic_functions.h (revision 321767) +++ branches/PHP_5_3/ext/standard/basic_functions.h (working copy) @@ -208,6 +208,10 @@ /* var.c */ zend_class_entry *incomplete_class; + struct { + long max_vars; + long num_vars; + } unserialize; /* url_scanner_ex.re */ url_adapt_state_ex_t url_adapt_state_ex; Index: branches/PHP_5_3/ext/standard/var.c =================================================================== --- branches/PHP_5_3/ext/standard/var.c (revision 321767) +++ branches/PHP_5_3/ext/standard/var.c (working copy) @@ -923,8 +923,9 @@ int buf_len; const unsigned char *p; php_unserialize_data_t var_hash; + long max_vars = PG(max_input_vars); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buf, &buf_len) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &buf, &buf_len, &max_vars) == FAILURE) { RETURN_FALSE; } @@ -934,10 +935,13 @@ p = (const unsigned char*) buf; PHP_VAR_UNSERIALIZE_INIT(var_hash); + PHP_VAR_UNSERIALIZE_MAX_VARS(max_vars); if (!php_var_unserialize(&return_value, &p, p + buf_len, &var_hash TSRMLS_CC)) { PHP_VAR_UNSERIALIZE_DESTROY(var_hash); zval_dtor(return_value); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + if (!BG(unserialize).max_vars || BG(unserialize).num_vars < BG(unserialize).max_vars) { + php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len); + } RETURN_FALSE; } PHP_VAR_UNSERIALIZE_DESTROY(var_hash); Index: branches/PHP_5_3/ext/standard/php_var.h =================================================================== --- branches/PHP_5_3/ext/standard/php_var.h (revision 321767) +++ branches/PHP_5_3/ext/standard/php_var.h (working copy) @@ -21,6 +21,7 @@ #ifndef PHP_VAR_H #define PHP_VAR_H +#include "ext/standard/basic_functions.h" #include "ext/standard/php_smart_str_public.h" PHP_FUNCTION(var_dump); @@ -57,10 +58,15 @@ #define PHP_VAR_UNSERIALIZE_INIT(var_hash) \ (var_hash).first = 0; \ - (var_hash).first_dtor = 0 + (var_hash).first_dtor = 0; \ + BG(unserialize).num_vars = 0; \ + BG(unserialize).max_vars = 0 + #define PHP_VAR_UNSERIALIZE_DESTROY(var_hash) \ var_destroy(&(var_hash)) +#define PHP_VAR_UNSERIALIZE_MAX_VARS(max_vars) BG(unserialize).max_vars = max_vars + PHPAPI void var_replace(php_unserialize_data_t *var_hash, zval *ozval, zval **nzval); PHPAPI void var_push_dtor(php_unserialize_data_t *var_hash, zval **val); PHPAPI void var_destroy(php_unserialize_data_t *var_hash); Index: branches/PHP_5_3/ext/standard/var_unserializer.re =================================================================== --- branches/PHP_5_3/ext/standard/var_unserializer.re (revision 321767) +++ branches/PHP_5_3/ext/standard/var_unserializer.re (working copy) @@ -269,6 +269,7 @@ FREE_ZVAL(key); return 0; } + --(BG(unserialize).num_vars); if (Z_TYPE_P(key) != IS_LONG && Z_TYPE_P(key) != IS_STRING) { zval_dtor(key); @@ -398,6 +399,11 @@ limit = cursor = *p; + if (BG(unserialize).max_vars && BG(unserialize).num_vars >= BG(unserialize).max_vars) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unserialized variables exceeded %ld", BG(unserialize).max_vars); + return 0; + } + if (var_hash && cursor[0] != 'R') { var_push(var_hash, rval); } @@ -425,7 +431,7 @@ *rval = *rval_ref; Z_ADDREF_PP(rval); Z_SET_ISREF_PP(rval); - + ++(BG(unserialize).num_vars); return 1; } @@ -449,6 +455,7 @@ Z_ADDREF_PP(rval); Z_UNSET_ISREF_PP(rval); + ++(BG(unserialize).num_vars); return 1; } @@ -456,6 +463,7 @@ *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_NULL(*rval); + ++(BG(unserialize).num_vars); return 1; } @@ -463,6 +471,7 @@ *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_BOOL(*rval, parse_iv(start + 2)); + ++(BG(unserialize).num_vars); return 1; } @@ -490,6 +499,7 @@ *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_LONG(*rval, parse_iv(start + 2)); + ++(BG(unserialize).num_vars); return 1; } @@ -505,6 +515,7 @@ ZVAL_DOUBLE(*rval, -php_get_inf()); } + ++(BG(unserialize).num_vars); return 1; } @@ -515,6 +526,7 @@ *p = YYCURSOR; INIT_PZVAL(*rval); ZVAL_DOUBLE(*rval, zend_strtod((const char *)start + 2, NULL)); + ++(BG(unserialize).num_vars); return 1; } @@ -543,6 +555,7 @@ INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 1); + ++(BG(unserialize).num_vars); return 1; } @@ -572,6 +585,7 @@ INIT_PZVAL(*rval); ZVAL_STRINGL(*rval, str, len, 0); + ++(BG(unserialize).num_vars); return 1; } @@ -588,6 +602,7 @@ array_init_size(*rval, elements); + ++(BG(unserialize).num_vars); if (!process_nested_data(UNSERIALIZE_PASSTHRU, Z_ARRVAL_PP(rval), elements, 0)) { return 0; } @@ -599,6 +614,7 @@ INIT_PZVAL(*rval); + ++(BG(unserialize).num_vars); return object_common2(UNSERIALIZE_PASSTHRU, object_common1(UNSERIALIZE_PASSTHRU, ZEND_STANDARD_CLASS_DEF_PTR)); } @@ -701,6 +717,7 @@ *p = YYCURSOR; if (custom_object) { + ++(BG(unserialize).num_vars); int ret = object_custom(UNSERIALIZE_PASSTHRU, ce); if (ret && incomplete_class) { @@ -717,6 +734,7 @@ } efree(class_name); + ++(BG(unserialize).num_vars); return object_common2(UNSERIALIZE_PASSTHRU, elements); } Index: branches/PHP_5_3/main/rfc1867.c =================================================================== --- branches/PHP_5_3/main/rfc1867.c (revision 321767) +++ branches/PHP_5_3/main/rfc1867.c (working copy) Index: branches/PHP_5_4/ext/standard/php_var.h =================================================================== --- branches/PHP_5_4/ext/standard/php_var.h (revision 321767) +++ branches/PHP_5_4/ext/standard/php_var.h (working copy) @@ -95,9 +95,12 @@ @@ -95,9 +95,13 @@ } else { \ (var_hash_ptr) = (php_serialize_data_t)BG(unserialize).var_hash; \ ++BG(unserialize).level; \ - } \ + } \ + BG(unserialize).num_vars = 0; \ + BG(unserialize).max_vars = 0; \ } while (0) +#define PHP_VAR_UNSERIALIZE_MAX_VARS(max_vars) BG(unserialize).max_vars = max_vars; + |
Copyright © 2001-2024 The PHP Group All rights reserved. |
Last updated: Thu Apr 25 17:01:29 2024 UTC |