]> granicus.if.org Git - php/commitdiff
Improved max_input_vars directive to check nested variables
authorDmitry Stogov <dmitry@php.net>
Tue, 14 Feb 2012 08:58:52 +0000 (08:58 +0000)
committerDmitry Stogov <dmitry@php.net>
Tue, 14 Feb 2012 08:58:52 +0000 (08:58 +0000)
main/php_variables.c
main/rfc1867.c

index 01969842b233b4ef4ada9b0ea04208341b20db84..427966170c8f37cb4bd78112ce7f4b9dc2603b43 100644 (file)
@@ -183,18 +183,9 @@ PHPAPI void php_register_variable_ex(char *var_name, zval *val, zval *track_vars
                        } else {
                                if (zend_symtable_find(symtable1, index, index_len + 1, (void **) &gpc_element_p) == FAILURE
                                        || Z_TYPE_PP(gpc_element_p) != IS_ARRAY) {
-                                       if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
-                                               if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
-                                                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
-                                               }
-                                               MAKE_STD_ZVAL(gpc_element);
-                                               array_init(gpc_element);
-                                               zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
-                                       } else {
-                                               zval_dtor(val);
-                                               free_alloca(var_orig, use_heap);
-                                               return;
-                                       }
+                                       MAKE_STD_ZVAL(gpc_element);
+                                       array_init(gpc_element);
+                                       zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
                                }
                        }
                        symtable1 = Z_ARRVAL_PP(gpc_element_p);
@@ -231,14 +222,7 @@ plain_var:
                                zend_symtable_exists(symtable1, index, index_len + 1)) {
                                zval_ptr_dtor(&gpc_element);
                        } else {
-                               if (zend_hash_num_elements(symtable1) <= PG(max_input_vars)) {
-                                       if (zend_hash_num_elements(symtable1) == PG(max_input_vars)) {
-                                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
-                                       }
-                                       zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
-                               } else {
-                                       zval_ptr_dtor(&gpc_element);
-                               }
+                               zend_symtable_update(symtable1, index, index_len + 1, &gpc_element, sizeof(zval *), (void **) &gpc_element_p);
                        }
                }
        }
@@ -249,6 +233,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(php_std_post_handler)
 {
        char *var, *val, *e, *s, *p;
        zval *array_ptr = (zval *) arg;
+       long count = 0;
 
        if (SG(request_info).post_data == NULL) {
                return;
@@ -262,6 +247,10 @@ last_value:
                if ((val = memchr(s, '=', (p - s)))) { /* have a value */
                        unsigned int val_len, new_val_len;
 
+                       if (++count > PG(max_input_vars)) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
+                               return;
+                       }
                        var = s;
 
                        php_url_decode(var, (val - s));
@@ -295,6 +284,7 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
        zval *array_ptr;
        int free_buffer = 0;
        char *strtok_buf = NULL;
+       long count = 0;
        
        switch (arg) {
                case PARSE_POST:
@@ -384,6 +374,11 @@ SAPI_API SAPI_TREAT_DATA_FUNC(php_default_treat_data)
                        }
                }
 
+               if (++count > PG(max_input_vars)) {
+                       php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
+                       break;
+               }
+
                if (val) { /* have a value */
                        int val_len;
                        unsigned int new_val_len;
index b848126b2a9e1b4b87d4c47f7289cb95237f3b2f..5da3a99355581c966859257deb10ff9db6d6c501 100644 (file)
@@ -691,6 +691,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
        php_rfc1867_getword_t getword;
        php_rfc1867_getword_conf_t getword_conf;
        php_rfc1867_basename_t _basename;
+       long count = 0;
 
        if (php_rfc1867_encoding_translation(TSRMLS_C) && internal_encoding) {
                getword = php_rfc1867_getword;
@@ -861,7 +862,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
                                        }
                                }
 
-                               if (sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) {
+                               if (++count <= PG(max_input_vars) && sapi_module.input_filter(PARSE_POST, param, &value, value_len, &new_val_len TSRMLS_CC)) {
                                        if (php_rfc1867_callback != NULL) {
                                                multipart_event_formdata event_formdata;
                                                size_t newlength = new_val_len;
@@ -879,15 +880,21 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* {{{ */
                                                new_val_len = newlength;
                                        }
                                        safe_php_register_variable(param, value, new_val_len, array_ptr, 0 TSRMLS_CC);
-                               } else if (php_rfc1867_callback != NULL) {
-                                       multipart_event_formdata event_formdata;
-
-                                       event_formdata.post_bytes_processed = SG(read_post_bytes);
-                                       event_formdata.name = param;
-                                       event_formdata.value = &value;
-                                       event_formdata.length = value_len;
-                                       event_formdata.newlength = NULL;
-                                       php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC);
+                               } else {
+                                       if (count == PG(max_input_vars) + 1) {
+                                               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Input variables exceeded %ld. To increase the limit change max_input_vars in php.ini.", PG(max_input_vars));
+                                       }
+                               
+                                       if (php_rfc1867_callback != NULL) {
+                                               multipart_event_formdata event_formdata;
+
+                                               event_formdata.post_bytes_processed = SG(read_post_bytes);
+                                               event_formdata.name = param;
+                                               event_formdata.value = &value;
+                                               event_formdata.length = value_len;
+                                               event_formdata.newlength = NULL;
+                                               php_rfc1867_callback(MULTIPART_EVENT_FORMDATA, &event_formdata, &event_extra_data TSRMLS_CC);
+                                       }
                                }
 
                                if (!strcasecmp(param, "MAX_FILE_SIZE")) {