php / php/php-src

fopen creates files with utf characters under certain conditions

未关闭
#13,640 10 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

还没有人认领这个 Issue。

Bug Category: Filesystem OS: Windows Status: Needs Triage
主要语言
C
星标
40.4k
派生
8.2k
平均合并
2 天 13 小时
30 天内合并 PR
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:

  1. 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.
  2. restart Apache
  3. 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.
  4. 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

贡献指南

打开贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 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

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。