php / php/php-src

fopen creates files with utf characters under certain conditions

Ouverte
#13,640 10 commentaires 0 réactions 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Category: Filesystem OS: Windows Status: Needs Triage
Langage dominant
C
Étoiles
40.4k
Forks
8.1k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

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

Guide de contribution

Ouvrir le guide de contribution

Par où commencer

  1. Lisez l'issue en entier, puis le guide de contribution du projet.
  2. Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
  3. Forkez le dépôt et travaillez sur une branche.
  4. Ouvrez une pull request qui référence le numéro de l'issue.

Piste de recherche

Commencez avec le script de reproduction fourni sur PHP 8.3.3 sous Apache sur Windows, en exécutant fopen(), file_exists(), default_charset et des requêtes keep-alive dans l’ordre d’onglets indiqué. Suivez le comportement lié aux fichiers entre les threads Apache réutilisés et comparez les requêtes avant et après la modification de default_charset. Le travail est terminé lorsque les noms de fichiers non latins restent cohérents quel que soit l’ordre des requêtes ou la réutilisation de la connexion.

Rédigé par le modèle d'indexation à partir du texte de l'issue.

Évaluation

Stack technique
apache, php
Domaine
backend, operating-systems
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
35/100

Recevez les nouvelles issues par e-mail

Un résumé court des issues GitHub adaptées aux débutants.