fopen creates files with utf characters under certain conditions
まだ誰も着手していません。
- 主要言語
- C
- スター
- 40.4k
- フォーク
- 8.1k
- 平均マージ
- 2日 13時間
- マージ済み PR(30日)
- 96
説明
Description
The following code:
if (@$_GET["charset"]) echo("set charset from ".ini_set("default_charset", "Windows-1251")."<BR>\n");
//ini_set("default_charset", "Windows-1251");
$FN="C:/Temp/АБВГДЕЖЗ.txt"; //no UTF here!
echo("filename: ".$FN."<BR>\n");
$hFile=fopen($FN, 'w'); fwrite($hFile, $FN); fclose($hFile);
Resulted in this output: the created file was C:\TEMP\АБВГДЕЖЗ.txt
(filename got converted to Utf-8)
But I expected this output instead: the file should be C:\TEMP\АБВГДЕЖЗ.txt
Explanation:
"АБВГДЕЖЗ" here are the first letters of Russian abc. They could be any other Russian letters or non-latin letters of another non-English language / charset.
The initial setting of default_charset for me is UTF-8 (as returned by ini_set()).
This is not a trivial bug and it's not easy to reproduce it, yet it is possible.
It only happens if a script calls ini_set("default_charset", "Windows-1251");
It is related to Apache's keep-alive connections reused for later requests.
Steps to reproduce:
- open 2 tabs in your browser, one with the script as is (for ex. dev.php) and another with charset parameter (dev.php?charset=1). If you run both tabs now they both will work correct.
- restart Apache
- refresh the 1st tab first several times (at least 2, the more the better). This creates Apache threads with a context of Utf-8. The created file is Ok.
- refresh the 2nd tab once. It creates a filename with Utf-8 characters. The reason is it is processed by a thread that just served the same script without changing default_charset.
For some time, no matter how many times you refresh 2nd tab, the file created will have Utf chars. But after some time the phenomenon will stop. Also, the bug may show even without restarting Apache, if you first call 1st tab many times, then wait for some time, like 2-3 minutes. But it takes longer.
This bug affects other files-related functions like file_exists() etc.
Both Php and Apache have been upgraded to their last versions: Apache/2.4.58 (Win64) PHP/8.3.3
PHP Version
8.3.3
Operating System
Windows 8.1
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
Windows 上の Apache で PHP 8.3.3 を使用し、提供された再現スクリプトから開始して、指定されたタブの順序で fopen()、file_exists()、default_charset、および keep-alive リクエストを実行します。再利用された Apache スレッド間でファイル関連の動作を追跡し、default_charset の変更前後でリクエストを比較します。リクエストの順序や接続の再利用に関係なく、非ラテン文字のファイル名が一貫していれば完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- apache, php
- 領域
- backend, operating-systems
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100