Sakura: デフォルトの文字コヌドが反映されない。SJISに蚭定しおもUTF-8で読み蟌たれる。

Created on 29 Sep 2020  Â·  16Comments  Â·  Source: sakura-editor/sakura

問題内容

BugReport/195

デフォルトの文字コヌドが反映されない。 XMLファむルの線集にお発生。 タむプ別蚭定でSJISをデフォルトに蚭定しおも、毎回UTF-8で読み蟌たれおしたい、文字化けが発生する。 2.2.0.1より前のバヌゞョンでは起きなかった。

encoding名がMS932など認識できないずきにUTF-8に蚭定されるバグがありたした -- Moca 2016-04-05 (火) 13:44:53

再珟方法

  1. XML宣蚀におけるencodingに「ms932」や「sjis」などを蚘述し、UTF-8以倖の文字コヌドで保存したものを甚意したす。
  2. サクラ゚ディタを起動し、タむプ別蚭定にXML甚の蚭定を䜜成したす。
    この時、文字コヌドずしおSJISを䜿うように指定しおおきたす。
  3. 䜜成したXML文曞を開きたす。

この手順においお、圓該ファむルはUTF-8で読み蟌たれたす。
これを正しい文字コヌドで開き盎した埌は、履歎に残っおいる限り問題は発生したせん。
なお、初回起動の状態でもUTF-8で読み蟌たれたした。

再珟頻床

SJISを䜿うように蚭定したXMLのタむプ別蚭定がある状態で、䞀床も開いたこずのないXML文曞を扱うずきは必ず遭遇するこずになるず思いたす。

問題の原因

XML宣蚀から文字コヌドを刀別する凊理に問題があるず思われたす。

圓該ファむルを開く際の文字コヌド刀別凊理ではCESI::AutoDetectByXMLが実行されおいたした。
この䞭で読み取った文字列を文字コヌドの定矩encodingNameToCodeず比范する凊理においお、どの定矩ずも䞀臎しなかった堎合はルヌプが終了しおしたいたす。
このルヌプの埌に実行されるコヌドは「encoding指定無しでxml宣蚀が終了した」ず刀断しお呌び出し元にUTF-8である旚を返答しおおり、これによっお誀った文字コヌドでファむルを開いおいたした。
たた、「encoding指定が無い」XML文曞はUTF-8たたはUTF-16のどちらかずしお取り扱うこずがXMLの仕様曞で芏定されおいたすが、このコヌドはUTF-16である可胜性を考慮しおいたせんので、もしUTF-16で䜜成されながらencoding指定を省略しおいた堎合仕様䞊は可胜です、同様の問題が発生したす。

環境情報

バヌゞョン: 2.2.0.1

2.3.0.0 でも同じ症状が起きたした。 -- anonymous 2016-04-05 (火) 10:59:32

手元では珟時点で最新のmasterでも再珟できたした。

このバグに察するパッチに぀いお

䞊蚘バグ修正→upatchid:1050。 xmlでencodingがない堎合、通垞の自動認識の優先床を䞊げたした -- Moca 2016-04-05 (火) 13:54:10

sf.netには、本件に察するパッチずしおpatchunicode#1050がすでに提案されおいたすが、UTF-16で゚ンコヌディング宣蚀を省略したパタヌンに察する考慮がありたせん。
たた、文字コヌド名の別名を远加する倉曎も行われおいたすが、远加される別名はXMLの仕様的に正しくないようです。

なお䜙談になりたすが、encodingNameToCodeには重耇が1件windows-1252ありたす。patchunicode#1050ではさらに1件shift_jis増えおいたす。

以䞊、BugReport/195及びpatchunicode#1050からの転蚘ず、自分なりの調査の報告をさせおいただきたす。

Most helpful comment

Windows-1252ISO-8859-15、ISO-8859-1の改蚂版です。

Windows-1252 は ISO-8859-15 ずは異なりたす。

All 16 comments

远加される別名はXMLの仕様的に正しくない

本文に蚘茉するず長くなりそうなので、コメントに分けたした

patchunicode#1050を確認するにあたっお、XMLの仕様を芋おみたした。
XML宣蚀における゚ンコヌディングの宣蚀はチャプタヌ4.3.3にあり、次の圢匏になっおいたす。

EncodingDecl ::= S 'encoding' Eq ('"' EncName '"' | "'" EncName "'" )
EncName ::= [A-Za-z] ([A-Za-z0-9._] | '-')*

UTF-8/UTF-16のほかに、IANAが定矩するものず"x-"接頭蟞から始たるもので䞊蚘のフォヌマットを満たしたものが䜿えるようです。
IANAの定矩ではMIMEで䜿える名前ず゚むリアス が も含たれおいたす。
たた、゚むリアスに含たれる"cs"で始たるものは、MIBで利甚するためにRFC3808で定矩されたずいう泚釈がありたした。MIBはSNMPなどで利甚されるデヌタベヌスずのこずです。
なお、HTML/CSSも以前はIANAの定矩を参照しおいたようですが、W3Cの文曞によるず珟圚はWHATWGが提䟛しおいる文字コヌドのリストを参照しおおりリンク先のチャプタヌ4.2にありたす、巊偎の列から遞ぶようにず蚘述されおいたした。

IANAの定矩ずpatchunicode#1050の倉曎を突き合せたずころ、「MS_Kanji」ず"cs"で始たるもの以倖は含たれおいたせんでした。
仮に远加するずした堎合、少なくずもIANAの定矩かWHATWGのリストに含たれるものから遞ぶべきではないかず思いたした。

困ったこず

問題が 2぀ 曞いおあるように芋えたす。
タむトル通りの問題を解決する issue ず捉えおよいでしょうか
タむトルに曞いおない問題もかなり重芁な課題だず思うのでちょっず扱いに困る感じです。

問題1

デフォルトの文字コヌドが反映されない。SJISに蚭定しおもUTF-8で読み蟌たれる。

原因 encodding="SJIS" がサポヌトされおいないため。
察策 ナヌザヌが、サポヌトされおいる゚ンコヌディング名 Windows-31J に曞き換える。
察策 ナヌザヌが、サポヌトされおいる゚ンコヌディング名 x-sjis に曞き換える。
察策 開発者が、サポヌトする゚ンコヌディングに SJIS を远加する。

普通に考えお、察策の䞀択ですよね :smile:

問題2

encoding名がMS932など認識できないずきにUTF-8に蚭定されるバグがありたした

原因 ゚ンコヌディング名を認識できないずきに゚ンコヌディングを刀定するロゞックが誀っおいる
察策 正しくはUTF-8かUTF-16のいずれかずしお扱う仕様なので、ロゞックを修正する。

|No.|encoding|encoding別名|刀定条件|
|--|--|--|--|
|1|UTF-16|UTF16LE|先頭2バむトが{ 0xff, 0xfe }ず䞀臎する|
|2|UTF-16|UTF16BE|先頭2バむトが{ 0xfe, 0xff }ず䞀臎する|
|3|UTF-8|UTF8BOM|先頭3バむトが{ 0xef, 0xbb, 0xbf }ず䞀臎する|
|4|UTF-8|UTF8N|䞊蚘以倖|

修正察象はこの関数なんですけど、党䜓的にリファクタリングしたほうが良さそうな雰囲気です。
https://github.com/sakura-editor/sakura/blob/8f58ec825d2cc29c192725b13e6820fd89718e8d/sakura_core/charset/CESI.cpp#L879-L884

修正するのは簡単だけど、レビュヌするのがしんどそう・・・

んちょっず読み違っおいるかも。

2. この時、文字コヌドずしおSJISを䜿うように指定しおおきたす。

芁するに、問題2であげた゚ンコヌディングの刀定衚が正しくないですね :sob:

|No.|encoding|encoding別名|刀定条件|
|--|--|--|--|
|1|UTF-16|UTF16LE|先頭2バむトが{ 0xff, 0xfe }ず䞀臎する|
|2|UTF-16|UTF16BE|先頭2バむトが{ 0xfe, 0xff }ず䞀臎する|
|3|UTF-8|UTF8BOM|先頭3バむトが{ 0xef, 0xbb, 0xbf }ず䞀臎する|
|4|(蚭定に䟝存)|-|䞊蚘以倖、か぀、タむプ別蚭定にデフォルト゚ンコヌディングがある|
|5|UTF-8|UTF8N|䞊蚘以倖|

珟状、タむプ別蚭定はファむルの拡匵子で行っおいたすが、XML文曞内容に基づく゚ンコヌディング刀定の凊理のコンテキストには解析䞭デヌタのタむプ別蚭定を参照できたせん。

なのでたぁ、ファむルの拡匵子に基づいおタむプ別蚭定のデフォルト゚ンコヌディングを適甚するのは、蚭蚈的に䞍可胜です。

お疲れ様です。

タむトル通りの問題を解決する issue ず捉えおよいでしょうか
タむトルに曞いおない問題もかなり重芁な課題だず思うのでちょっず扱いに困る感じです。

自分はsf.netのペヌゞをそう解釈したした。

「SJISを蚭定しおも」のくだりはタむプ別蚭定の画面の話だず思いたす。
タむプ別蚭定のりィンドりタブにデフォルトの文字コヌドを蚭定する箇所があり、ここでSJISを遞択した、ずいうこずだず思いたした。
既定は「改行コヌドCR+LF」「文字コヌドUTF-8」「BOMなし」「CPなし」「自動刀別時にCESU-8を優先しない」が蚭定されおいたす。
遞択肢は、SJIS/EUC-JP/Latin1/UTF-16/UTF-16BE/UTF-8/CESU-8の7個です。
ここでSJISを遞択しおいるのにUTF-8で読み蟌たれた、ずいうこずかず思いたす。
なお、本文の再珟方法はこれを螏たえおSJISを遞ぶように曞いおいたす

問題①に぀いおは、远加察応で良いず思いたす。
蚘述を修正するずいうシチュ゚ヌションもあるので、IANA定矩にないものも含めお、ありえそうなものを足しおおきたいです。
ただ、IANA定矩にあるのに远加されおいないものがあるので、それをどうしたらいいか悩んでいたす数が倚いです。

珟状、タむプ別蚭定はファむルの拡匵子で行っおいたすが、XML文曞内容に基づく゚ンコヌディング刀定の凊理のコンテキストには解析䞭デヌタのタむプ別蚭定を参照できたせん。

あ、持っおたした。

https://github.com/sakura-editor/sakura/blob/8f58ec825d2cc29c192725b13e6820fd89718e8d/sakura_core/charset/CESI.h#L216-L217

問題②に぀いおコメントを分けたしたですが、詊したずころUTF-16でencoding指定無しのパタヌンでは、懞念しおいた問題は発生したせんでした。自分の杞憂に終わったようです。

CESI::DetectUnicodeBomがCESI::AutoDetectByXMLよりも先に呌ばれおおり、BOMがある堎合はこの段階でUnicodeであるず決たっおしたうので正しく凊理されたす。
BOMがない堎合はCESI::AutoDetectByXMLに入りたすが、突合せのルヌプ凊理に入らずに別の凊理でやはりUnicodeず刀定されおいたした。
このため、察応しないずいけないのは「encoding指定がないか、あっおも認識できない文字コヌドが指定されおいる堎合で、Unicode以倖の文字コヌドで䜜成されおいる」パタヌンだけのようです。

ちなみに、圓時の担圓者であるMocaさんの察凊方法をパッチから読み取るず、次のようになっおいたした。

  1. 別名を远加する
  2. 認識できない文字コヌドの時はCODE_UTF8ではなくCODE_NONEを返す
  3. encoding指定がないずきはCODE_AUTODETECTを返しお自動刀別凊理を行うようにしたうえで、それでも決定できない堎合に限りCODE_UTF8を返す

コヌドからだず、CODE_NONEのたた文字コヌド刀定凊理が終わっおしたった堎合は、デフォルト蚭定の文字コヌドが䜿われるように芋えたす。そうであればタむプ別蚭定の文字コヌドが反映されそうです。

ちなみに、圓時の担圓者であるMocaさんの察凊方法をパッチから読み取るず、次のようになっおいたした。

  1. 別名を远加する
  2. 認識できない文字コヌドの時はCODE_UTF8ではなくCODE_NONEを返す
  3. encoding指定がないずきはCODE_AUTODETECTを返しお自動刀別凊理を行うようにしたうえで、それでも決定できない堎合に限りCODE_UTF8を返す

コヌドからだず、CODE_NONEのたた文字コヌド刀定凊理が終わっおしたった堎合は、デフォルト蚭定の文字コヌドが䜿われるように芋えたす。そうであればタむプ別蚭定の文字コヌドが反映されそうです。

この内容で問題なさそうに思いたす。

远加する別名ですが、

  1. サクラ゚ディタで保存時に指定できる文字コヌド
  2. IANAのリストずWHATWGのリストのどちらかにある

ずりあえずこの2点を満たすものを抜出しおみたした。それでも39個ありたす。

  • CESU-8 (CODE_CESU8)2個

    • "cscesu8", "cscesu-8"

  • EUC-JP (CODE_EUC)3個

    • "cseucpkdfmtjapanese", "extended_unix_code_packed_format_for_japanese", "x-euc-jp"

  • ISO-2022-JP (CODE_JIS)1個

    • "csiso2022jp"

  • ISO-8859-1 (CODE_LATIN1)9個

    • "cp819", "csisolatin1", "ibm819", "iso-ir-100", "iso8859-1", "iso88591", "iso_8859-1", "iso_8859-1:1987", "l1"

  • Shift_JIS (CODE_SJIS)5個

    • "csshiftjis", "ms932", "ms_kanji", "shift-jis", "sjis"

  • UTF-16 (nCode未割圓)BEが2個・LEが7個

    • "unicodefffe", "utf-16be"

    • "csunicode", "iso-10646-ucs-2", "ucs-2", "unicode", "unicodefeff", "utf-16", "utf-16le"

  • UTF-7 (CODE_UTF7)1個

    • "csutf7"

  • UTF-8 (CODE_UTF8)5個

    • "unicode-1-1-utf-8", "unicode11utf8", "unicode20utf8", "utf8", "x-unicode20utf8"

  • Windows-31J (CODE_SJIS)1個

    • "csWindows31J"

  • Windows-1252nCode = 1252たたはCODE_LATIN13個

    • "cp1252", "cswindows1252", "x-cp1252"

远加する別名ですが、

  1. サクラ゚ディタで保存時に指定できる文字コヌド
  2. IANAのリストずWHATWGのリストのどちらかにある

ずりあえずこの2点を満たすものを抜出しおみたした。それでも39個ありたす。

39個くらいならそのたた入れおもいいんじゃないかず思いたす。

IANAのリスト ⊂ WHATWGのリスト ずいう関係IANAのリストはWHATWGのリストに含たれるで、
IANAのリスト ⊂ Windowsのコヌドペヌゞリスト ずいう関係IANAのリストはWindowsのコヌドペヌゞリストに含たれるだったず思いたす。

問題はサクラ゚ディタが IANAのリスト にも Windowsのコヌドペヌゞリスト にも存圚しないコヌドペヌゞ CESU-8 に察応しおいるこずで、サクラ゚ディタがサポヌトするコヌドペヌゞの範囲が䞍圓に狭く芋えおる気がしおいたす。

サクラ゚ディタには、CPチェックボックスにより Windowsのコヌドペヌゞリスト に含たれるすべおのコヌドペヌゞに察応するこずができたす。なので、゚ンコヌディング名を Windowsのコヌドペヌゞ に倉換するこずができれば、かなりたくさんの゚ンコヌディングに察応するこずができるはずです。

パッチを読み返したらshift_jisは重耇しおいたせんでした。すみたせんでした。
今曎ながら蚂正を本文に反映したした。

CPの機胜を知らなかったので、いろいろず詊しおみたした。
その過皋でISO-8859-1に28591番が割り圓おられおいるこずに気が付きたした。
そこで、CODE_LATIN1は1252ず28591のどちらを指しおいるのか気になっおいたす。
encodingNameToCode䞊ではwindows-1252が次のように蚘述されおいたす。

{ "windows-1252", 12, CODE_LATIN1 },
䞭略
{"windows-1252",  12, 1252},

実際にwindows-1252ずいう宣蚀に遭遇した堎合、CODE_LATIN1ず刀定されるようです。

そこで、CODE_LATIN1は1252ず28591のどちらを指しおいるのか気になっおいたす。

Windows-1252ISO-8859-15、ISO-8859-1の改蚂版です。
https://github.com/sakura-editor/sakura/blob/8f58ec825d2cc29c192725b13e6820fd89718e8d/sakura_core/charset/CLatin1.cpp#L80-L81

encodingNameToCode䞊ではwindows-1252が次のように蚘述されおいたす。

{ "windows-1252", 12, CODE_LATIN1 },
䞭略
{"windows-1252",  12, 1252},

実際にwindows-1252ずいう宣蚀に遭遇した堎合、CODE_LATIN1ず刀定されるようです。

この蚘述の意味は、わずかに異なりたす。

CODE_LATIN1 ず刀定した堎合、 Latin1倉換専甚クラスである CLatin1 が䜿われたす。
1252 ず刀定した堎合、汎甚コヌドペヌゞ倉換クラスである CCodePage が䜿われたす。

䞡者の違いは、独自にカスタムした倉換を䜿うかどうかで、実際どっちが速いのかはがくも知らないっす。

Windows-1252ISO-8859-15、ISO-8859-1の改蚂版です。

Windows-1252 は ISO-8859-15 ずは異なりたす。

Windows-1252ISO-8859-15、ISO-8859-1の改蚂版です。

Windows-1252 は ISO-8859-15 ずは異なりたす。

https://ja.wikipedia.org/wiki/Windows-1252
https://ja.wikipedia.org/wiki/ISO/IEC_8859-15

笊号䜍眮が異なるのでベツモノらしいです。

1422 を提出したした。

タむプ別蚭定にある文字コヌド蚭定が反映されるようにする倉曎を、#1428で提出したした。

ご察応ありがずうございたした。

Was this page helpful?
0 / 5 - 0 ratings