Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CCodeBaseの変換テストを追加する #1614

Merged
merged 1 commit into from Mar 31, 2021

Conversation

berryzplus
Copy link
Contributor

PR の目的

文字コード変換に関するテストを追加します。

カテゴリ

  • その他の問題

PR の背景

サクラエディタには、各種「文字コード」でエンコードされたファイルを開くための「コード変換機能」があります。

コード変換機能は、各種文字コードの仕様が「やや難解」であることもあり、長いことごく一部の「偉い人」ないし「偉そうな人」による寡占でメンテされてきた経緯があるっぽいです。

ぶっちゃけで言うと間違ってる部分がかなりあるんですけど「誰もが分かるような状態」で誤りを指摘することが大変難しく、「分かっているけど修正できない既知の問題」が溜まってきていると思います。

今回は「コード変換機能」に単体テストを用意することにより、
間違っていたら直す、という当たり前のことができる環境を作ってみます。

PR のメリット

  • 文字コード変換のテストが書けるようになります。
  • Shift-JISの文字コード変換について、ほぼ完全な仕様を確認できます。
  • 今後、挙動の怪しい変換を見つけたら、少しテストコードを追加すれば容易に検証できるようになります。

PR のデメリット (トレードオフとかあれば)

  • 実装過程で 3件の不具合 を発見しましたが、あえて修正していません。
  • CCodeBaseに対してラッパーインターフェースを追加していますが、これが「従来のインターフェースだとテスト書きにくいんじゃ、ヴォケ」という主張の表れであることを読み取って、心を痛める歴代の開発者がいるかも知れません。

仕様・動作説明

サクラエディタは、編集するテキストファイルを内部的に「拡張UTF16LE」に変換しています。

この変換に使うのが CCodeBase 派生クラス で、今回のテスト対象です。

CCodeBase派生クラスは2つの変換メソッドを持っています。

メソッド名 役割
CodeToUnicode ファイルデータを内部データに変換する。
UnicodeToCode 内部データをファイルデータに変換する。

世の中には色々な文字コードがあります。

文字コード名 説明 表現できる文字の数
SHIFT-JIS Windows 3.1日本語版が世に出るときに作られた文字コード。 約1万文字
EUC-JP 拡張UNIXコード。古いLinuxで使われていた文字コード。 約8万文字
UTF-8 Unicodeを8bit単位で符号化したもの。 約100万文字
UTF-16 Unicodeを16bit単位で符号化したもの。 約100万文字

見て分かる通り、Unicodeとそうでないものでは表現できる文字数に圧倒的な差があります。

サクラエディタはこの特性を活用して、すべての文字をUnicodeに変換しようとします。
変換できなかったら、変換できないなりにデータを破壊しないように拡張文字として保持します。

  • SHIFT-JIS変換の例

    変換元文字 変換結果
    普通の文字 Unicode文字に変換。
    NEC選定IBM拡張文字 エンコードして保持。
    SHIFT-JIS範囲外 エンコードして保持。

    「エンコードする」ということは「デコードできる」ということです。

本当はテスト追加と同時に既知の不具合を直してしまいたかったんですが、それをやるとレビューが成立しないような気がしたので、いったん無理なく実装できる部分だけに留め、問題解決は先送りすることにしました。

PR の影響範囲

このPRは既存処理を変更するものではありません。

テスト内容

テストで利用するために、本体にラッパーインターフェースを追加しています。
追加コードについては単体テストで利用しているため、追加のテストは不要と考えています。

関連 issue, PR

参考資料

無理なく実装できる部分を先行して実装する。
@sonarcloud
Copy link

sonarcloud bot commented Mar 29, 2021

Kudos, SonarCloud Quality Gate passed!

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

100.0% 100.0% Coverage
0.0% 0.0% Duplication

@berryzplus berryzplus marked this pull request as ready for review March 29, 2021 14:33
@AppVeyorBot
Copy link

@berryzplus
Copy link
Contributor Author

レビューありがとうございます。マージしちゃいます。

  • 実装過程で 3件の不具合 を発見しましたが、あえて修正していません。

ちなみにこの3件の内訳は以下の通りです。

  1. Shift-JISで変換できなかった文字がある場合に、変換結果が「正常」になる。
  2. EUC-JPで補助漢字が正しく取り込みできない。
  3. UTF32BEで7bit ASCII文字列の取り込みができない。

これらの不具合修正と CConvertMediator をテスト可能にする変更のどちらを優先するかで迷い中っす。

@berryzplus
Copy link
Contributor Author

概要

  • EUC-JPで補助漢字が正しく取り込みできない。

修正検討した結果、「補助漢字には対応しない仕様」のEUCが実装されてることが分かりました。
つまり、「森鷗外」を正しく取りこめないのはバグでなく「仕様」です。

詳細

EUCは Enhanced UNIX Code なんですが、複数のバージョンが存在します。

日本語コードの担い手がアメリカにある UNIX団体 ではなく、
日本の Linuxコミュニティ により行われてきた経緯が関係すると思われます。

EUCはそもそも、日本語のエンコーディングにJIS漢字コードを使用します。
JIS漢字コードは日本の工業規格団体JISが策定した日本語文字を2bytesで表現するコード体系です。
EUCはJIS漢字コードに「ある数値」を足し込むことにより日本語文字の最上位ビットが必ず立つように調整したものです。
ShirtJISもこのJIS漢字コードを利用していますが、先行バイトに制限があるShiftJisよりもEUCのほうが扱える値域が少し広いです。

ぼくが認識していた「本来のEUC」というのは、
JIS漢字コードが定める「補助漢字」に対応したEUCを指していました。
補助漢字に対応したEUCは、サクラエディタのEUCよりも少し新しいバージョンです。

現在のサクラエディタEUCは、
Unicode⇔ShiftJis⇔JIS⇔EUC
という前提に基づいて実装されています。

登場する文字セットで扱える文字数の関係は以下のようになっています。
Unicode > JIS ≧ EUC > ShiftJis

※Unicode は [0, 0x10FFFF] の範囲で、最大4bytes
※JISは2bytesで文字を定義するが、補助漢字表が別。今後増えない保証はない。
※EUCは半角カナと常用漢字を2bytesで表現するが、補助漢字は3bytesで表現する。
※ShiftJISは全角文字を2bytesで表現する。3bytes形式がないため最も値域が狭い。

課題

  1. サクラエディタEUCは現状のままでよいか?
    現状の実装はおそらく、最初期のEUC実装。
    仕様として「誤り」ではないものの、これのために「普通(?)のEUC」が扱えないとするとマイナス。
  2. 正しいEUCってなんだろう?
    現代のUNIXで日本語を扱いたい場合、UTF-8を使うことになっています。
    このため、「最新のEUCに合わせる」の対処がミビョーになります。

windowsでコードページ20932を使えば、EUCっぽいコード変換が可能ですが、これの位置づけも不明点があるので、どっかしら「えいやっ!」と決めてしまう部分が必要になると思っています。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants