Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,9 @@ PHP NEWS
contains null bytes. (Weilin Du)
. parse_str() now raises a ValueError when the $string argument contains
null bytes. (Weilin Du)
. request_parse_body() now emits a warning and falls back to the
max_input_vars ini setting for negative max_input_vars option values.
(Xu Chen)
. proc_open() now raises a ValueError when the $cwd argument contains
null bytes. (Weilin Du)
. ini_get_all() now includes the built-in default value in the details.
Expand Down
3 changes: 3 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ PHP 8.6 UPGRADE NOTES
contains null bytes.
. parse_str() now raises a ValueError when the $string argument contains
null bytes.
. request_parse_body() now emits a warning and falls back to the
max_input_vars ini setting when the $options argument contains a negative
max_input_vars value.
. linkinfo() now raises a ValueError when the $path argument is empty.
. pathinfo() now raises a ValueError when an invalid $flag
argument value is passed.
Expand Down
22 changes: 18 additions & 4 deletions ext/standard/http.c
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ PHP_FUNCTION(http_build_query)
}
/* }}} */

static zend_result cache_request_parse_body_option(HashTable *options, zval *option, int cache_offset)
Comment thread
LamentXU123 marked this conversation as resolved.
static zend_result cache_request_parse_body_option(zval *option, int cache_offset, const char *non_negative_option_name)
{
if (option) {
zend_long result;
Expand All @@ -265,6 +265,11 @@ static zend_result cache_request_parse_body_option(HashTable *options, zval *opt
zend_value_error("Invalid %s value in $options argument", zend_zval_value_name(option));
return FAILURE;
}
if (non_negative_option_name && result < 0) {
zend_error(E_WARNING, "\"%s\" option in $options argument must be greater than or equal to 0", non_negative_option_name);
SG(request_parse_body_context).options_cache[cache_offset].set = false;
return SUCCESS;
}
SG(request_parse_body_context).options_cache[cache_offset].set = true;
SG(request_parse_body_context).options_cache[cache_offset].value = result;
} else {
Expand All @@ -290,7 +295,15 @@ static zend_result cache_request_parse_body_options(HashTable *options)

#define CHECK_OPTION(name) \
if (zend_string_equals_literal_ci(key, #name)) { \
if (cache_request_parse_body_option(options, value, REQUEST_PARSE_BODY_OPTION_ ## name) == FAILURE) { \
if (cache_request_parse_body_option(value, REQUEST_PARSE_BODY_OPTION_ ## name, NULL) == FAILURE) { \
return FAILURE; \
} \
continue; \
}

#define CHECK_NON_NEGATIVE_OPTION(name) \
if (zend_string_equals_literal_ci(key, #name)) { \
if (cache_request_parse_body_option(value, REQUEST_PARSE_BODY_OPTION_ ## name, #name) == FAILURE) { \
return FAILURE; \
} \
continue; \
Expand All @@ -300,7 +313,7 @@ static zend_result cache_request_parse_body_options(HashTable *options)
case 'm':
case 'M':
CHECK_OPTION(max_file_uploads);
CHECK_OPTION(max_input_vars);
CHECK_NON_NEGATIVE_OPTION(max_input_vars);
CHECK_OPTION(max_multipart_body_parts);
break;
case 'p':
Expand All @@ -317,7 +330,8 @@ static zend_result cache_request_parse_body_options(HashTable *options)
return FAILURE;
} ZEND_HASH_FOREACH_END();

#undef CACHE_OPTION
Comment thread
LamentXU123 marked this conversation as resolved.
#undef CHECK_OPTION
#undef CHECK_NON_NEGATIVE_OPTION

return SUCCESS;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
--TEST--
request_parse_body() negative max_input_vars option falls back to ini setting
--INI--
max_input_vars=1
--ENV--
REQUEST_METHOD=PUT
--POST_RAW--
Content-Type: multipart/form-data; boundary=---------------------------84000087610663814162942123332
-----------------------------84000087610663814162942123332
Content-Disposition: form-data; name="field1"

post field data
-----------------------------84000087610663814162942123332
Content-Disposition: form-data; name="field2"

post field data
-----------------------------84000087610663814162942123332--
--FILE--
<?php

try {
[$_POST, $_FILES] = request_parse_body([
'max_input_vars' => -1,
]);
} catch (Throwable $e) {
echo get_class($e), ': ', $e->getMessage(), "\n";
}

var_dump($_POST, $_FILES);

?>
--EXPECTF--
Warning: "max_input_vars" option in $options argument must be greater than or equal to 0 in %s on line %d
RequestParseBodyException: Input variables exceeded 1. To increase the limit change max_input_vars in php.ini.
array(0) {
}
array(0) {
}
Loading