sakura-editor / sakura

SAKURA Editor (Japanese text editor for MS Windows)
https://sakura-editor.github.io/
Other
1.24k stars 162 forks source link

UTF-32ビッグエンディアンにて、基本多言語面以外を正しく表示する #1913

Closed hiroki-oogakiuchi closed 1 year ago

hiroki-oogakiuchi commented 1 year ago

PR対象

カテゴリ

PR の背景

issueは作成していません。以下、不具合の再現手順です。 基本多言語面以外の文字(U+10000以降)を入力します。この例では、U+1F604です。

1

12001(UTF-32BE)にて保存します。

2

警告が表示されます。この警告が表示されることが1個目の不具合です。無視して[はい]を押下します。

3

保存直後、画面表示上は、正しく見えます。

4

バイナリーエディターで見ても、正しく保存されています。(拡張子の違いは無視してください)

7

一度、サクラエディタを閉じて、先ほど保存したファイルを12001(UTF-32BE)にて開きます。

5

文字化けしています。符号位置も間違っています。これが2個目の不具合です。

6

上記手順は、BOM有りの場合でも同様です。また、12000(UTF-32LE)では正しく動作しています。

不具合箇所の特定

保存時、 CCodePage::S_UnicodeToUTF32BE→ CCodePage::S_UTF32BEToUnicode→(警告表示)→ CCodePage::S_UnicodeToUTF32BE の順に呼ばれます。 開くとき、 CCodePage::S_UTF32BEToUnicode→ CCodePage::S_UTF32BEToUnicode の順に呼ばれます。 それぞれ、なぜ同じ処理が2回呼ばれるのか、リファクタリングしたいですが、今回はパスします。

CCodePage::S_UnicodeToUTF32BE、839~842行目の変換は正しいので、正しく保存できています。

CCodePage::S_UTF32BEToUnicode、617行目の if( pSrcByte[i] == 0x00 && pSrcByte[i+1] <= 0x10 ) が、U+10000以降の条件になります。

その後、620行目の UINT c = (pSrcByte[i+3] << 16) | (pSrcByte[i+2] << 8) | pSrcByte[i+1]; は、UTF-32の1文字分のchar4個(先頭は0x00)を4byteの変数に入れるのですが、 UTF-32リトルエンディアンの同様箇所、CCodePage::S_UTF32LEToUnicode、530行目 UINT c = (pSrcByte[i+2] << 16) | (pSrcByte[i+1] << 8) | pSrcByte[i]; と比較して、ここではpSrcByteの並びが逆になるだけで、cは同じ値になるはずです。

UTF-32BE 0x00,0x01,0xF6,0x04を、c=0x0001F604

UTF-32LE 0x04,0xF6,0x01,0x00を、c=0x0001F604

よって、620行目を UINT c = (pSrcByte[i+1] << 16) | (pSrcByte[i+2] << 8) | pSrcByte[i+3]; のように修正しました。

テスト内容

不具合再現と同じ手順で、警告無く正しく保存できること、開いたときに文字化けせずに表示できることを確認しました。

8

UTF-32ビッグエンディアンは滅多に使用されることはありませんが、テキストエディターの基本機能に関わることなので、 関係者の皆さん、よろしくお願いします。

sonarcloud[bot] commented 1 year ago

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

0.0% 0.0% Coverage
0.0% 0.0% Duplication

AppVeyorBot commented 1 year ago

:white_check_mark: Build sakura 1.0.4287 completed (commit https://github.com/sakura-editor/sakura/commit/3d610ad30e by @hiroki-oogakiuchi)