[php-src] Issue #24606: mbstring.http_input is ignored in subsequent requests after changing default_charset

From: Date: Fri, 23 Oct 2026 15:25:49 +0000
Subject: [php-src] Issue #24606: mbstring.http_input is ignored in subsequent requests after changing default_charset
Groups: php.bugs 
Request: Send a blank email to php-bugs+get-253132@lists.php.net to get a copy of this message
Issue: https://github.com/php/php-src/issues/24606 Author: OddOnes ### Description With mbstring.http_input=auto explicitly configured, calling ini_set('default_charset', 'UTF-8') in one request causes the effective HTTP input encoding candidates to change for subsequent requests handled by the same process. The INI value remains auto, but mb_http_input('I') returns only EUC-JP, and UTF-8 POST data is corrupted. ### Reproduction PHP must have mbstring enabled. Save the following configuration as php.ini: ```ini default_charset = EUC-JP input_encoding = "" mbstring.language = Japanese mbstring.encoding_translation = On mbstring.http_input = auto mbstring.internal_encoding = EUC-JP display_errors = stderr error_reporting = E_ALL & ~E_DEPRECATED ``` Save the following code as index.php: ```php <?php header('Content-Type: application/json; charset=UTF-8'); echo json_encode([ 'pid' => getmypid(), 'default_charset' => ini_get('default_charset'), 'http_input_ini' => ini_get('mbstring.http_input'), 'candidates' => mb_http_input('I'), 'detected_post' => mb_http_input('P'), 'post_hex' => bin2hex($_POST['text'] ?? ''), ], JSON_UNESCAPED_SLASHES), "\n"; if (isset($_GET['change'])) { ini_set('default_charset', 'UTF-8'); } ``` Start a fresh built-in server from the directory containing these files: ```sh unset PHP_CLI_SERVER_WORKERS php -c ./php.ini -S 127.0.0.1:18983 -t . ``` In another terminal, send the following two requests in order. Both send the same UTF-8 string, 日本語テスト. The first request changes default_charset after printing the initial state. ```sh body='text=%E6%97%A5%E6%9C%AC%E8%AA%9E%E3%83%86%E3%82%B9%E3%83%88' curl --data "$body" 'http://127.0.0.1:18983/index.php?change=1' curl --data "$body" 'http://127.0.0.1:18983/index.php' ``` ### Actual output ```text {"pid":7,"default_charset":"EUC-JP","http_input_ini":"auto","candidates":["ASCII","JIS","UTF-8","EUC-JP","SJIS"],"detected_post":"UTF-8","post_hex":"c6fccbdcb8eca5c6a5b9a5c8"} {"pid":7,"default_charset":"EUC-JP","http_input_ini":"auto","candidates":["EUC-JP"],"detected_post":"EUC-JP","post_hex":"3fa5e63f3f3f3f3f3fb9e33f3f"} ``` PID values may differ, but both requests must be handled by the same PID. The second request has the original default_charset and still reports mbstring.http_input=auto. However, its effective candidate list contains only EUC-JP. The converted POST value contains replacement characters (3f, or ?). ### Expected output The second request should retain the explicitly configured input candidates and convert the POST value correctly, just as the first request does: ```text {"pid":7,"default_charset":"EUC-JP","http_input_ini":"auto","candidates":["ASCII","JIS","UTF-8","EUC-JP","SJIS"],"detected_post":"UTF-8","post_hex":"c6fccbdcb8eca5c6a5b9a5c8"} ``` ### Additional verification The same behavior was reproduced in Docker with: - PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12, using both the built-in server and FPM with a single worker. - PHP 7.4.0, using the built-in server. It was not reproduced with PHP 7.3.33 using the built-in server. Adding input_encoding=auto to php.ini prevents the corruption in these tests. Explicitly listing the five encodings in mbstring.http_input does not prevent it. ### Suspected cause The relevant hook and flags were introduced in commit: https://github.com/php/php-src/commit/f73f190c3f97479f735b97c22a8e4885344edca1 PHP_RSHUTDOWN_FUNCTION(mbstring) clears http_input_set before modified INI settings are restored. Restoring default_charset then invokes mbstring_internal_encoding_changed_hook(), which rebuilds the persistent HTTP input list from php_get_input_encoding(). With an empty input_encoding, this returns EUC-JP. The next request does not restore the explicitly configured mbstring.http_input candidate list. This reproducer requires sequential HTTP requests handled by the same process, rather than a single CLI execution. ### PHP Version ```plain PHP Version PHP 8.5.12 (cli) (built: Oct 21 2026 15:48:53) (NTS) Copyright (c) The PHP Group Built by https://github.com/docker-library/php Zend Engine v4.5.12, Copyright (c) Zend Technologies with Zend OPcache v8.5.12, Copyright (c), by Zend Technologies ``` ### Operating System Debian GNU/Linux 13 (trixie), Docker image php:8.5.12-cli, x86_64d

« previous php.bugs (#253132) next »