php / php/php-src

mb_strtoupper converts non-alphabetic characters in Shift_JIS (CP932)

Ouverte
#12,412 6 commentaires 1 réaction 0 personnes assignées Voir sur GitHub

Personne n'a encore pris cette issue.

Bug Extension: mbstring Status: Needs Triage
Langage dominant
C
Étoiles
40.4k
Forks
8.2k
Merge moyen
2 j 13 h
PR mergées (30 j)
96

Description

Description

mb_strtoupper converts non-alphabetic characters in Shift_JIS (CP932)

var_dump(
    "\x81\xE0" === mb_strtoupper("\x87\x90", 'cp932')
);

\x81\xE0 and \x87\x90 mean (U+2252: Approximately Equal to or the Image Of).

var_dump(
    "\u{2252}" === mb_convert_encoding("\x81\xE0", 'utf-8', 'cp932'),
    "\u{2252}" === mb_convert_encoding("\x87\x90", 'utf-8', 'cp932')
);

\x87\x90 is the one of NEC special characters and was registered in duplicate for historical reasons.

The unintended conversion is caused by a round-trip conversion between Unicode and Shift_JIS.

var_dump(
    "\x81\xE0" === roundtrip("\x87\x90", 'cp932'),
    "\x81\xE0" === roundtrip("\x81\xE0", 'cp932')
);

function roundtrip($char, $enc) {
    return mb_convert_encoding(mb_convert_encoding($char, 'utf-8', $enc), $enc, 'utf-8');
}

As far as I know, 398 characters in Shift_JIS are affected by round-trip conversion. The test code is here.

The same problem applies to mb_scrub, mb_strtolower, mb_convert_case.

var_dump(
    "\x81\xE0" === mb_scrub("\x87\x90", 'cp932'),
    "\x81\xE0" === mb_strtolower("\x87\x90", 'cp932'),
    "\x81\xE0" === mb_strtoupper("\x87\x90", 'cp932'),
    "\x81\xE0" === mb_convert_case("\x87\x90", MB_CASE_TITLE, 'cp932')
);
PHP Version

PHP 8.2.10

Operating System

Debian 11.7 (Google ChromeOS 117.0)

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

Reproduisez les exemples CP932 fournis et utilisez les points d’entrée mb_scrub, mb_strtolower, mb_strtoupper et mb_convert_case comme périmètre initial. Le travail est considéré comme terminé lorsque la séquence de caractères NEC dupliquée reste distincte de sa séquence CP932 canonique, au lieu d’être modifiée par une conversion aller-retour, et que le comportement concerné est couvert par des tests.

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

Évaluation

Stack technique
php
Domaine
internationalization
Type d'issue
Bug
Difficulté
4/5
Temps estimé
3-5 jours
Activité
À l'abandon
Clarté
Plutôt claire
Accessibilité débutants
38/100

Recevez les nouvelles issues par e-mail

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