Skip to content

Commit 44be3c5

Browse files
author
OracleNep
committed
Reject negative request_parse_body() max_input_vars option
1 parent 425cd3d commit 44be3c5

4 files changed

Lines changed: 74 additions & 4 deletions

File tree

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,8 @@ PHP NEWS
226226
contains null bytes. (Weilin Du)
227227
. parse_str() now raises a ValueError when the $string argument contains
228228
null bytes. (Weilin Du)
229+
. request_parse_body() now raises a ValueError for negative max_input_vars
230+
option values. (OracleNep)
229231
. proc_open() now raises a ValueError when the $cwd argument contains
230232
null bytes. (Weilin Du)
231233
. ini_get_all() now includes the built-in default value in the details.

UPGRADING

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,8 @@ PHP 8.6 UPGRADE NOTES
142142
contains null bytes.
143143
. parse_str() now raises a ValueError when the $string argument contains
144144
null bytes.
145+
. request_parse_body() now raises a ValueError when the $options argument
146+
contains a negative max_input_vars value.
145147
. linkinfo() now raises a ValueError when the $path argument is empty.
146148
. pathinfo() now raises a ValueError when an invalid $flag
147149
argument value is passed.

ext/standard/http.c

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ PHP_FUNCTION(http_build_query)
247247
}
248248
/* }}} */
249249

250-
static zend_result cache_request_parse_body_option(HashTable *options, zval *option, int cache_offset)
250+
static zend_result cache_request_parse_body_option(zval *option, int cache_offset, const char *non_negative_option_name)
251251
{
252252
if (option) {
253253
zend_long result;
@@ -265,6 +265,10 @@ static zend_result cache_request_parse_body_option(HashTable *options, zval *opt
265265
zend_value_error("Invalid %s value in $options argument", zend_zval_value_name(option));
266266
return FAILURE;
267267
}
268+
if (non_negative_option_name && result < 0) {
269+
zend_value_error("\"%s\" option in $options argument must be greater than or equal to 0", non_negative_option_name);
270+
return FAILURE;
271+
}
268272
SG(request_parse_body_context).options_cache[cache_offset].set = true;
269273
SG(request_parse_body_context).options_cache[cache_offset].value = result;
270274
} else {
@@ -290,7 +294,15 @@ static zend_result cache_request_parse_body_options(HashTable *options)
290294

291295
#define CHECK_OPTION(name) \
292296
if (zend_string_equals_literal_ci(key, #name)) { \
293-
if (cache_request_parse_body_option(options, value, REQUEST_PARSE_BODY_OPTION_ ## name) == FAILURE) { \
297+
if (cache_request_parse_body_option(value, REQUEST_PARSE_BODY_OPTION_ ## name, NULL) == FAILURE) { \
298+
return FAILURE; \
299+
} \
300+
continue; \
301+
}
302+
303+
#define CHECK_NON_NEGATIVE_OPTION(name) \
304+
if (zend_string_equals_literal_ci(key, #name)) { \
305+
if (cache_request_parse_body_option(value, REQUEST_PARSE_BODY_OPTION_ ## name, #name) == FAILURE) { \
294306
return FAILURE; \
295307
} \
296308
continue; \
@@ -300,7 +312,7 @@ static zend_result cache_request_parse_body_options(HashTable *options)
300312
case 'm':
301313
case 'M':
302314
CHECK_OPTION(max_file_uploads);
303-
CHECK_OPTION(max_input_vars);
315+
CHECK_NON_NEGATIVE_OPTION(max_input_vars);
304316
CHECK_OPTION(max_multipart_body_parts);
305317
break;
306318
case 'p':
@@ -317,7 +329,8 @@ static zend_result cache_request_parse_body_options(HashTable *options)
317329
return FAILURE;
318330
} ZEND_HASH_FOREACH_END();
319331

320-
#undef CACHE_OPTION
332+
#undef CHECK_OPTION
333+
#undef CHECK_NON_NEGATIVE_OPTION
321334

322335
return SUCCESS;
323336
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
--TEST--
2+
request_parse_body() rejects negative max_input_vars option values
3+
--FILE--
4+
<?php
5+
6+
$invalidOptions = [
7+
['max_input_vars', -1],
8+
['max_input_vars', '-1'],
9+
['max_input_vars', '-1M'],
10+
['max_input_vars', '-1.0'],
11+
];
12+
13+
foreach ($invalidOptions as [$name, $value]) {
14+
try {
15+
request_parse_body([$name => $value]);
16+
} catch (Throwable $e) {
17+
echo $name, ': ', get_class($e), ': ', $e->getMessage(), "\n";
18+
}
19+
}
20+
21+
$acceptedOptions = [
22+
['max_input_vars', 0],
23+
['max_file_uploads', -1],
24+
['post_max_size', -1],
25+
['post_max_size', 0],
26+
['upload_max_filesize', '-1M'],
27+
['upload_max_filesize', 0],
28+
['max_multipart_body_parts', -1],
29+
];
30+
31+
foreach ($acceptedOptions as [$name, $value]) {
32+
try {
33+
request_parse_body([$name => $value]);
34+
} catch (Throwable $e) {
35+
echo $name, ': ', get_class($e), ': ', $e->getMessage(), "\n";
36+
}
37+
}
38+
39+
?>
40+
--EXPECTF--
41+
max_input_vars: ValueError: "max_input_vars" option in $options argument must be greater than or equal to 0
42+
max_input_vars: ValueError: "max_input_vars" option in $options argument must be greater than or equal to 0
43+
max_input_vars: ValueError: "max_input_vars" option in $options argument must be greater than or equal to 0
44+
45+
Warning: Invalid quantity "-1.0": unknown multiplier "0", interpreting as "-1" for backwards compatibility in %s on line %d
46+
max_input_vars: ValueError: "max_input_vars" option in $options argument must be greater than or equal to 0
47+
max_input_vars: RequestParseBodyException: Request does not provide a content type
48+
max_file_uploads: RequestParseBodyException: Request does not provide a content type
49+
post_max_size: RequestParseBodyException: Request does not provide a content type
50+
post_max_size: RequestParseBodyException: Request does not provide a content type
51+
upload_max_filesize: RequestParseBodyException: Request does not provide a content type
52+
upload_max_filesize: RequestParseBodyException: Request does not provide a content type
53+
max_multipart_body_parts: RequestParseBodyException: Request does not provide a content type

0 commit comments

Comments
 (0)