« ブラウザ別EUC-JP補助漢字のサポート状況(1) | トップページ | 【PHPのとあるエラー】Warning: fopen(): URL file-access is disabled in the server configuration in »

2008/01/03

ブラウザ別EUC-JP補助漢字などのサポート状況(2)



EUC-JP補助漢字(JIS X 212)の処理をPHPやPerlなどにてどのように処理すべきかを考えるために、ここで、補助漢字の各種ブラウザ別対応状況を引き続き調べてみたいと思います。

Windows版IEは補助漢字に関して、数値文字参照や文字実体参照で全て処理しようとしますが、そのようにして送信されたデータがデーベースに保存され、それを使って表示しているWEBサイトを想定してみます。この際、他のブラウザが見たときに正しく表示されるのかをまとめてみたいと思います。

実験2-1:各種ブラウザは、補助漢字や補助漢字外の韓国語や記号に関して、Windows版IE形式で符合された文字列を意図通りに表示できるか?(EUC-JPのページで)
「鷗外」「髙﨑」「möchte」「안녕하세요?」「©♦」でテストしました。
IE7(Vista)※1これは当たり前。
IE6(XP SP2)
IE5.5(Windows 2000)
Firefox 2.0.0.11
(Vista)
※1IEの「言葉」をFirefoxは理解できます。
Firefox 3.0β2
(Vista)
Firefox 1.0.8
(XP SP2)
Netscape 7.1
(Vista)
Opera 9.25(Vista)※1Opera 9.25の符号方法はWindows版IEと全く同じなので、これも当たり前。
Opera 9.5β1
(Vista)
※1IEの「言葉」をOpera 9.5は理解できます。
Safari 3.0.5
(Vista)
一部×「髙﨑」については×。
(ただし、フォントの設定によって表示できるようになる可能性もあるかもしれません。フォント依存文字の可能性があるかもしれません。)
Safari 3.0.5
(Tiger 10.4.11)
IE 5.2.3
(Tiger 10.4.11)
一部×「髙﨑」については×。ただし、ここで注目すべきは、Mac版IEではこれらの補助漢字を自身では入力することが全く駄目だったのに、表示に関してはかなりの部分クリアできていることです。
Firefox 2.0.0.11
(Tiger 10.4.11)
※1ダイヤのマーク(♦)だけが期待通りに表示されませんが、コピーして調べたりしてみると別の文字に文字化けしているわけではなく、コードポイントに変化はないようです。フォントを適切に設定することで表示されるのかも?
Safari 2.0.4
(Tiger 10.4.8)
一部×「髙﨑」については×。

※1 ただし、多くのWEBアプリケーションで「&」をエスケープします(このこと自体は正しい処理です。)が、数値文字参照や文字実体参照の存在を考慮していないことがほとんどのため、これらの文字は意図通りに表示されないことが多いのも事実です。

これがhtmlspecialcharsの仕様について、ここ数日間いろいろ調べていたきっかけであり、いろいろ書きなぐってきた記事の最初の出発点です。そもそも、「&」をエスケープしなければならないのはなぜか?に始まって、やっぱりエスケープしないといけないんだという結論に至るまで相当の時間が必要だったのですが、「HTMLの仕様がそうなんだから」とかいう理由ではなく、実例で理解したかったので、これはこれでよかったと思います。


実験2-2:各種ブラウザは、補助漢字や補助漢字外の韓国語や記号に関して、Firefox形式で符合された文字列を意図通りに表示できるか?(EUC-JPのページで)
「鷗外」「髙﨑」「möchte」「안녕하세요?」「©♦」でテストしました。
IE7(Vista)×IEは、Firefoxの「言葉」が理解できません。これは痛すぎます。

「鷗外」は「乗ス外」に文字化けします。(この文字化けのメカニズムについては、森山先生の解説をお読みください。)

「möchte」は「m醇rchte」に文字化けします。「©♦」は「潤・」に文字化けしますが、本来は問題の無い次の文字(♦)まで道連れにして文字化けします。

「髙﨑」に関しては、FirefoxがWindows版IEに仕様を合わせてくれているので(「合わせている」気持ちはないかもしれませんが・・・)、文字化けしません。補助漢字にも入らない韓国語は文字化けしないという皮肉な結果に。
IE6(XP SP2)
IE5.5(Windows 2000)
Firefox 2.0.0.11
(Vista)
これは当たり前。
Firefox 3.0β2
(Vista)
Firefox 1.0.8
(XP SP2)
Netscape 7.1
(Vista)
Opera 9.25(Vista)× 文字化けの仕方は、Windows版IEとは違いますが、文字化けします。
Opera 9.5β1
(Vista)
Firefoxと同じ仕様なので、○です。
Safari 3.0.5
(Vista)
× 自分自身は、0x8Fを使った3バイト文字での補助漢字の符号を行っていながら、どういうわけか、そのような文字を正しく表示できません。(フォントの設定の問題なのか、豆腐のような文字化けになります。
Safari 3.0.5
(Tiger 10.4.11)
一部× 自分自身は、0x8Fを使った3バイト文字での補助漢字の符号を行っていながら、どういうわけか、そのような文字を正しく表示できません。(Safari 2.0.4では起こらないので、これって退化? Windows版の文字化けはフォントの問題の可能性もありますが、Mac版Safari 3での現象は解せません。)
IE 5.2.3
(Tiger 10.4.11)
×補助漢字外のハングル文字及びダイヤマークだけOKという皮肉な結果に。

Firefoxの「言葉」をMac版IEでは理解できません。
Firefox 2.0.0.11
(Tiger 10.4.11)
ダイヤのマーク(♦)だけが期待通りに表示されませんが、コピーして調べたりしてみると別の文字に文字化けしているわけではなく、コードポイントに変化はないようです。フォントを適切に設定することで表示されるのかも?
Safari 2.0.4
(Tiger 10.4.8)
一部×「髙﨑」については×。

以上の結果を踏まえて、どちらの方式にプログラム側でデータを統一するかということを考えた場合、私には一目瞭然に思えます。Windows版IEの方式に合わせるべきでしょう。これは、単にWindows版IEのシェアの方がFirefoxより圧倒的に多いということだけではありません。

ブラウザ(Windows版IEとFirefoxのいずれか)の開発チームに仕様を変えるように言うことも選択肢かもしれませんが、そう簡単に仕様変更があるとは思えません。両者それぞれ深い考えがあってのことだと思います。ブラウザの側で統一されないなら、結局は、プログラム側で対応しなければならないでしょう。

ここで、Windows版IE派であれFirefox派であれ、「何でブラウザのバグなのにプログラムで対応しなければならないの?」 という疑問を持つ人もおられるかもしれません。非標準のバグっている仕様に敢えて対応することで、その悪しきバグを延命させるというか、認めてしまう結果になるとかいう発想も理解はできます。ただ、どちらの仕様が正しいかということも重要かもしれませんが、趣味のプログラマーやRFCそのものの研究家ならいざ知らず、実際に稼動している(or 稼動することを想定している)サイトのプログラムを作成されている人なら、どちらの仕様が正しいかということよりも、
  • 「サイトの利用者の利便を考えたときに、どうするのが一番いいか?」 を考えれば、どういう結論になるでしょうか?(「(ブラウザのバグだから)対処しなくてもいいでしょう?、社長!」といように社長に弁明する際に、「ブラウザのバグ(実装ミス)」を盾にすることは私も以前はよくありましたが・・・、私の場合、「対処すべきでない」という発想を自分自身が持ったことはなかったですね。)

  • 上記1は良い子ぶっているかもしれませんが、プログラマーの力の見せ所として、できるだけ他のサイトでは対応していないこともやってみたいと思う人なら、ブラウザのバグであれば、なおさら燃えないでしょうか? (もしくは、サイト訪問者からのクレームを受けたくない(馬鹿にされたくない)、というような後ろ向きの動機という場合もあるかもしれません。)

  • ビジネス的な観点(≒お金)から言っても、できるだけサイト利用者にとって嬉しい仕様のほうにしたいと考えた場合、ブラウザのバグだからとか言っておれないのではないでしょうか?

という疑問を持ってしまいます。

この際に、上記のテストでも明らかなように、補助漢字に対応しようとするのであれば※2Windows版IEの言葉はFirefoxは理解できるが、Firefoxの言葉はWindows版IEは理解できないのですから、Windows版IEの仕様に合わせるべきでしょう。そのようにすれば、文字化けになる確率がずっと減るのですから・・・(数値文字参照の「&問題」を解決できた場合)。Firefoxの方が賢いのですから、Windows版IEの仕様に合わせるべきだと思うのです。これは、別にFirefoxの開発チームに求めていることではなく、プログラマーがそのように仕様を合わせるべきだと思うのです。

※2  これを言ってしまえば終わりということになり、今更な発言ですが、補助漢字の処理で問題になるケースは実際にはそれほどないはずであり、対応しないというのも十分ありうる判断であるとは思います。

日本語や英語以外の言語で掲示板やブログでの書き込みをしたいという場合、及び「鷗外」「♦♠」などの記号を入れたい場合にのみ問題になりうることであり、ぶっちゃけた話、滅多にはないと思われるからです。ただ、ここでの議論は、もし「対応しようとするのであれば」という話になります。

PHPやPerlが標準で、そのような対応(2つの仕様のすり合わせ)をしてくれていたらベスト(≒「楽」)ですが、そうでないなら、プログラマーが自力で対応するしかないでしょう。(自分で作れないなら、補助漢字などの処理で問題になるケースははっきり言ってレアなケースでしょうから対応しないことにするか、他の献身的で優秀な方が既にライブラリーなどを公開していないか探すしかないでしょう。)

私が調べた限りでは、PHPやPerlが標準で、Firefoxなどの0x8F~の符号方法を数値文字参照にするような処理をしてくれる関数は準備されていないようです。ですから、対応しようとするのであれば、自力で対応するしかなさそうです。

具体的には、
  • 「髙・﨑・德・彅」などCP51932で対応できる漢字以外の補助漢字や、補助漢字にも入らない記号や外国語に関しては、数値文字参照で対応することとになるのですが、PHPで言うとhtmlspecialchars関数を通すと、「&」が「&」になって数値参照文字が破壊される問題がありますから、それに対応しなければなりません。これがまず第一点。

  • また、Firefoxの0x8Fで始まるデータを数値文字参照方式に変換しなければなりません。これが第二点です。

この際、「&」が「&」になって数値参照文字が破壊される問題を解決するために、そもそも「&」を「&」にする意味はどこにあるのか? というのを調べたのが「【PHPネタ】htmlspecialchars関数はサニタイズ関数? 」(昨年12月25日)の記事でした。

&」を「&」にする意味が例えば、セキュリティ的な理由であるならば、不用意に数値文字参照や文字実体参照を普通の文字に変換するのは危険かもしれません。最終結論的には、「【PHP関連】「&」(アンパサンド)をエスケープしなければならない実例」(昨年12月31日)の記事で書きましたように、表示上の問題だけでなく、セキュリティ的な意味でも「&#数字;」や「&アルファベット;」、「&#x16進数文字列;」をpreg_replace関数などで一律変換するのは危険だと書きました。

そのような意味で、「&」を「&」の処理を入れるのはホワイトリスト方式にするのが良いです。これが私が出した結論です。

リストは徐々に拡大させていくこともできるでしょうし、リストが多くなれば多くなるほど処理時間がかさみますし、その結果、ブラウザに出力表示されるのが遅くなり、サイト訪問者を待たせる結果になりますので、少なくとも最初はリストのサイズを抑えたほうがいいでしょう。

リストの作成は今回は手動でやりましたが、例えば、韓国語のコードポイントは一定の箇所に集中して現れますので、ここの部分はプログラムで変換用データを作成することは可能だと思います(ずいぶん前のことであり、遠い記憶なのですが、誰かが韓国語用のライブラリを公開していたと思ったのですが、見つけることができませんでした。)。

各自のサイトの仕様に合わせたホワイトリストを作成すれば、ブラウザでの表示レベルにおいては、文字化けが減るでしょう(テストはしていませんが、メール送信が絡んでくると、JISでメールを送信する仕様にしている限りは、文字化けを回避することは難しいと思います)。

実際にプログラムしてみると、下記のような感じになると思います。



● ホワイトリスト方式でやってみた正直な感想:
無茶苦茶面倒です。ブラックリスト方式でやってみたい誘惑に駆られましたが、これは駄目ですね。ホワイトリストの作成を効率的にできる方法も模索しないと駄目なようです。



|

トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/67411/17563288

この記事へのトラックバック一覧です: ブラウザ別EUC-JP補助漢字などのサポート状況(2):

コメント

コメントを書く