Skip to content

Commit 1ac68e7

Browse files
committed
Fix GH-8157: post_max_size evaluates .user.ini too late in php-fpm
This introduces new SAPI callback that runs before post read Closes GH-19333
1 parent 585e581 commit 1ac68e7

File tree

6 files changed

+80
-4
lines changed

6 files changed

+80
-4
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ PHP NEWS
2424
. Fix OSS-Fuzz #442954659 (Crash in exif_scan_HEIF_header). (nielsdos)
2525
. Various hardening fixes to HEIF parsing. (nielsdos)
2626

27+
- FPM:
28+
. Fixed GH-8157 (post_max_size evaluates .user.ini too late in php-fpm).
29+
(Jakub Zelenka)
30+
2731
- Opcache:
2832
. Fixed bug GH-19669 (assertion failure in zend_jit_trace_type_to_info_ex).
2933
(Arnaud)

main/SAPI.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -458,6 +458,10 @@ SAPI_API void sapi_activate(void)
458458
SG(request_parse_body_context).throw_exceptions = false;
459459
memset(&SG(request_parse_body_context).options_cache, 0, sizeof(SG(request_parse_body_context).options_cache));
460460

461+
if (sapi_module.pre_request_init) {
462+
sapi_module.pre_request_init();
463+
}
464+
461465
/* Handle request method */
462466
if (SG(server_context)) {
463467
if (PG(enable_post_data_reading)

main/SAPI.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -290,6 +290,8 @@ struct _sapi_module_struct {
290290
const char *ini_entries;
291291
const zend_function_entry *additional_functions;
292292
unsigned int (*input_filter_init)(void);
293+
294+
int (*pre_request_init)(void); /* called before activate and before the post data read - used for .user.ini */
293295
};
294296

295297
struct _sapi_post_entry {
@@ -340,6 +342,7 @@ END_EXTERN_C()
340342
0, /* phpinfo_as_text; */ \
341343
NULL, /* ini_entries; */ \
342344
NULL, /* additional_functions */ \
343-
NULL /* input_filter_init */
345+
NULL, /* input_filter_init */ \
346+
NULL /* pre_request_init */
344347

345348
#endif /* SAPI_H */

sapi/fpm/fpm/fpm_main.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -702,7 +702,7 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha
702702
}
703703
/* }}} */
704704

705-
static int sapi_cgi_activate(void) /* {{{ */
705+
static int sapi_cgi_pre_request_init(void)
706706
{
707707
fcgi_request *request = (fcgi_request*) SG(server_context);
708708
char *path, *doc_root, *server_name;
@@ -766,6 +766,11 @@ static int sapi_cgi_activate(void) /* {{{ */
766766

767767
return SUCCESS;
768768
}
769+
770+
static int sapi_cgi_activate(void) /* {{{ */
771+
{
772+
return SUCCESS;
773+
}
769774
/* }}} */
770775

771776
static int sapi_cgi_deactivate(void) /* {{{ */
@@ -1600,6 +1605,7 @@ int main(int argc, char *argv[])
16001605
sapi_startup(&cgi_sapi_module);
16011606
cgi_sapi_module.php_ini_path_override = NULL;
16021607
cgi_sapi_module.php_ini_ignore_cwd = 1;
1608+
cgi_sapi_module.pre_request_init = sapi_cgi_pre_request_init;
16031609

16041610
#ifndef HAVE_ATTRIBUTE_WEAK
16051611
fcgi_set_logger(fpm_fcgi_log);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
--TEST--
2+
FPM: gh8157 - post related INI settings not applied for .user.ini
3+
--SKIPIF--
4+
<?php include "skipif.inc"; ?>
5+
--FILE--
6+
<?php
7+
8+
require_once "tester.inc";
9+
10+
$cfg = <<<EOT
11+
[global]
12+
error_log = {{FILE:LOG}}
13+
[unconfined]
14+
listen = {{ADDR}}
15+
pm = dynamic
16+
pm.max_children = 5
17+
pm.start_servers = 1
18+
pm.min_spare_servers = 1
19+
pm.max_spare_servers = 3
20+
EOT;
21+
22+
$code = <<<EOT
23+
<?php
24+
var_dump(\$_POST);
25+
EOT;
26+
27+
$ini = <<<EOT
28+
post_max_size=10K
29+
html_errors=off
30+
EOT;
31+
32+
$tester = new FPM\Tester($cfg, $code);
33+
$tester->setUserIni($ini);
34+
$tester->start();
35+
$tester->expectLogStartNotices();
36+
$tester
37+
->request(
38+
headers: [ 'CONTENT_TYPE' => 'application/x-www-form-urlencoded'],
39+
stdin: 'foo=' . str_repeat('a', 20000),
40+
method: 'POST',
41+
)
42+
->expectBody([
43+
'Warning: PHP Request Startup: POST Content-Length of 20004 bytes exceeds the limit of 10240 bytes in Unknown on line 0',
44+
'array(0) {',
45+
'}',
46+
], skipHeadersCheck: true);
47+
$tester->terminate();
48+
$tester->close();
49+
50+
?>
51+
Done
52+
--EXPECT--
53+
Done
54+
--CLEAN--
55+
<?php
56+
require_once "tester.inc";
57+
FPM\Tester::clean();
58+
?>

sapi/fpm/tests/response.inc

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,18 +119,19 @@ class Response extends BaseResponse
119119
/**
120120
* @param mixed $body
121121
* @param string $contentType
122+
* @param bool $skipHeadersCheck
122123
*
123124
* @return Response
124125
*/
125-
public function expectBody($body, $contentType = 'text/html')
126+
public function expectBody($body, $contentType = 'text/html', bool $skipHeadersCheck = false)
126127
{
127128
if ($multiLine = is_array($body)) {
128129
$body = implode("\n", $body);
129130
}
130131

131132
if ( ! $this->checkIfValid()) {
132133
$this->error('Response is invalid');
133-
} elseif ( ! $this->checkDefaultHeaders($contentType)) {
134+
} elseif ( ! $skipHeadersCheck && ! $this->checkDefaultHeaders($contentType)) {
134135
$this->error('Response default headers not found');
135136
} elseif ($body !== $this->rawBody) {
136137
if ($multiLine) {

0 commit comments

Comments
 (0)