Skip to content

Commit bcad8b6

Browse files
committed
Reject negative request_parse_body() limit options
1 parent 425cd3d commit bcad8b6

2 files changed

Lines changed: 46 additions & 9 deletions

File tree

ext/standard/http.c

Lines changed: 13 additions & 9 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 *option_name, bool allow_negative)
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 (!allow_negative && result < 0) {
269+
zend_value_error("Invalid negative value for \"%s\" option in $options argument", 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 {
@@ -288,9 +292,9 @@ static zend_result cache_request_parse_body_options(HashTable *options)
288292
return FAILURE;
289293
}
290294

291-
#define CHECK_OPTION(name) \
295+
#define CHECK_OPTION(name, allow_negative) \
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, #name, allow_negative) == FAILURE) { \
294298
return FAILURE; \
295299
} \
296300
continue; \
@@ -299,25 +303,25 @@ static zend_result cache_request_parse_body_options(HashTable *options)
299303
switch (ZSTR_VAL(key)[0]) {
300304
case 'm':
301305
case 'M':
302-
CHECK_OPTION(max_file_uploads);
303-
CHECK_OPTION(max_input_vars);
304-
CHECK_OPTION(max_multipart_body_parts);
306+
CHECK_OPTION(max_file_uploads, false);
307+
CHECK_OPTION(max_input_vars, false);
308+
CHECK_OPTION(max_multipart_body_parts, true);
305309
break;
306310
case 'p':
307311
case 'P':
308-
CHECK_OPTION(post_max_size);
312+
CHECK_OPTION(post_max_size, false);
309313
break;
310314
case 'u':
311315
case 'U':
312-
CHECK_OPTION(upload_max_filesize);
316+
CHECK_OPTION(upload_max_filesize, false);
313317
break;
314318
}
315319

316320
zend_value_error("Invalid key \"%s\" in $options argument", ZSTR_VAL(key));
317321
return FAILURE;
318322
} ZEND_HASH_FOREACH_END();
319323

320-
#undef CACHE_OPTION
324+
#undef CHECK_OPTION
321325

322326
return SUCCESS;
323327
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
--TEST--
2+
request_parse_body() negative limit options
3+
--FILE--
4+
<?php
5+
6+
$invalidOptions = [
7+
'max_file_uploads' => -1,
8+
'max_input_vars' => -1,
9+
'post_max_size' => -1,
10+
'upload_max_filesize' => -1,
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+
try {
22+
request_parse_body(['max_multipart_body_parts' => -1]);
23+
} catch (Throwable $e) {
24+
echo 'max_multipart_body_parts: ', get_class($e), ': ', $e->getMessage(), "\n";
25+
}
26+
27+
?>
28+
--EXPECT--
29+
max_file_uploads: ValueError: Invalid negative value for "max_file_uploads" option in $options argument
30+
max_input_vars: ValueError: Invalid negative value for "max_input_vars" option in $options argument
31+
post_max_size: ValueError: Invalid negative value for "post_max_size" option in $options argument
32+
upload_max_filesize: ValueError: Invalid negative value for "upload_max_filesize" option in $options argument
33+
max_multipart_body_parts: RequestParseBodyException: Request does not provide a content type

0 commit comments

Comments
 (0)