Skip to content
Browse files

MDL-41451 - Large forms are truncated by max_input_vars

By parsing php://input in chunks, we can bypass max_input_vars for
forms which do not use the "multipart/form-data" enctype.  This can
be (and is) safely skipped if there are fewer than max_input_vars
fields submitted as part of $_POST.
  • Loading branch information...
1 parent b69ec28 commit 85b82a9c2fd12f4d997261302a823d2fd9f96097 @pauln pauln committed Aug 28, 2013
Showing with 34 additions and 2 deletions.
  1. +34 −2 lib/formslib.php
View
36 lib/formslib.php
@@ -261,10 +261,10 @@ function _process_submission($method) {
$submission = array();
if ($method == 'post') {
if (!empty($_POST)) {
- $submission = $_POST;
+ $submission = $this->_get_post_params();
}
} else {
- $submission = array_merge_recursive($_GET, $_POST); // emulate handling of parameters in xxxx_param()
+ $submission = array_merge_recursive($_GET, $this->_get_post_params()); // Emulate handling of parameters in xxxx_param().
}
// following trick is needed to enable proper sesskey checks when using GET forms
@@ -284,6 +284,38 @@ function _process_submission($method) {
}
/**
+ * Internal method. Gets all POST variables, bypassing max_input_vars limit if needed.
+ *
+ * @return array All POST variables as an array, in the same format as $_POST.
+ */
+ protected function _get_post_params() {
+ $enctype = $this->_form->getAttribute('enctype');
+ $max = (int)ini_get('max_input_vars');
+
+ if (empty($max) || count($_POST, COUNT_RECURSIVE) < $max || (!empty($enctype) && $enctype == 'multipart/form-data')) {
+ return $_POST;
+ }
+
+ // Large POST request with enctype supported by php://input.
+ // Parse php://input in chunks to bypass max_input_vars limit, which also applies to parse_str().
+ $allvalues = array();
+ $values = array();
+ $str = file_get_contents("php://input");
+ $delim = '&';
+
+ $chunks = array_map(function($p) use ($delim) {
+ return implode($delim, $p);
+ }, array_chunk(explode($delim, $str), $max));
+
+ foreach ($chunks as $chunk) {
+ parse_str($chunk, $values);
+ $allvalues = array_merge_recursive($allvalues, $values);
+ }
+
+ return $allvalues;
+ }
+
+ /**
* Internal method. Validates all old-style deprecated uploaded files.
* The new way is to upload files via repository api.
*

0 comments on commit 85b82a9

Please sign in to comment.
Something went wrong with that request. Please try again.