mbstring.http_input is ignored in subsequent requests after changing default_charset
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 4/5
- 見積もり時間
- 1〜2日
- 初心者へのやさしさ
- 48/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 活発
調査の方向性
Start by reading PHP_RSHUTDOWN_FUNCTION(mbstring) and mbstring_internal_encoding_changed_hook(), introduced in the linked commit, then trace how INI settings are restored between requests. Reproduce the issue with the supplied php.ini and two sequential requests handled by one server process. Done means the second request retains the configured HTTP input candidates and converts the UTF-8 POST data correctly.
索引モデルが issue の本文から書いたものです。
説明
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:
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
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:
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.
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
{"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:
{"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
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
- 主要言語
- C
- スター
- 40.7k
- フォーク
- 8.3k
- 平均マージ
- 2日 17時間
- マージ済み PR(30日)
- 159
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートなし
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
php/php-src のほかの issue
-
Bug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 70/100
メンテナーはふだん 1 日以内に返信
-
ext/mbstring: mb_regex_substitute() reads past the replacement string's end on a truncated trailing multibyte lead byte対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
php/php-src#24769 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
zend_set_local_var() overwrites existing compiled variable (CV) zval without calling zval_ptr_dtor()対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープンBug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
master: part of the mbstring bailout fix got lost in a merge対応中かも @lazerg が 6 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
Bug Status: Needs Triage
難易度 2/5 1〜3時間 初心者へのやさしさ 64/100
メンテナーはふだん 1 日以内に返信
似ている issue
-
documentation
難易度 1/5 1〜3時間 初心者へのやさしさ 91/100
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
メンテナーはふだん 1 日以内に返信
-
enhancement ui
難易度 1/5 1時間未満 初心者へのやさしさ 72/100
ChupathingyCE/chupathingyce#485 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 82/100
eclipse-paho/paho.mqtt.c#1727 ·
メンテナーはふだん 6 日以内に返信