[PHP-dev 1492] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

komura komura.db2r1e @ gmail.com
2009年 8月 21日 (金) 01:30:35 JST


komura です。

On Thu, 20 Aug 2009 02:11:39 +0900
Moriyoshi Koizumi <mozo @ mozo.jp> wrote:

> ところで、関連する別の問題を発見してしまいました。本来であれば U+FEFF は先頭にあるときのみ BOM
> としての役割を果たすため、挙動としては明らかにバグなのですが、コード列の中のいずれの箇所でも U+FFFE が出現すると、U+FEFF
> が出力された後、エンディアンが切り替わってしまうのです。

確認しました。この問題は見落としていました。
場当たり的なパッチは作成してみたのですが、あまり検証していませんので、
もう少し検証してから投稿するか考えます(既に小泉さんがパッチを書いて
おられるかもしれませんが)。

結果としては、以下のように、エンディアンが変更されずに、出力される
のが正しいのでしょうか?

<?php
var_dump(bin2hex(mb_convert_encoding("\xfe\xff\xff\xfe\x41\x00\x42\x00\x41\x00",
"UTF-16BE", "UTF-16")));
----
結果
string(20) "fefffffe410042004100"

それとも、0xfffe が BOM の位置以外で出現した場合は、不正文字列として
削除すべきでしょうか?
手元の iconv では削除するようです。ただ、iconv も本件と同じような問題
があるような気がします。

var_dump(bin2hex(iconv("UTF-16", "UTF-16BE",
"\xfe\xff\xff\xfe\x41\x00\x42\x00\x41\x00")));
----
結果
string(16) "fffe410042004100"


> >> > 4. mb_check_encoding() で UTF-16(Little Endian) を判定すると、必ず false を
> >> >   返す
...
> すみません、言葉足らずで、斜め読みでよく問題を理解していないのではないかと疑われても仕方ないのですが、
> これについては、仕様、という認識です。

了解しました。仕様ということで問題ないと思います。

 
> # いろいろな意見があるかと思いますが、個人的には、mb_check_encoding() 自体の有用性を疑っています。

これには同意します。
mb_check_encoding() 以外の方法で、文字エンコーディングの妥当性を正しく
検証できる手段があれば良いのですが・・・。

mb_check_encoding() の代替手段として、mb_detect_encoding() が使えないか
と調べたことがあったのですが、使えないという結論に至りました。今回、
報告した問題の他にも、UTF-16 など、一部の文字エンコーディングが判定
できない問題、UTF-8 で、冗長表現や、サロゲートペア領域を有効と判定
する問題など、多くの問題があるように思います。

現状では、文字エンコーディングを正確に判定したい場合は、正規表現を
使うのが妥当だろうと思います。


> なお、ICU への移行は決まったわけではないので、保守は続けていきます。

分かりました。ICU への移行には期待しています。

-- 
komura <komura.db2r1e @ gmail.com>


PHP-dev メーリングリストの案内