IEにおけるEUC-JPの処理方法でShift_JISがからんでくる件

http://d.hatena.ne.jp/hoshikuzu/20071018#p1

の続編。(私の中ではこちらを先に気がついたのですけれど。)

Fileを読めるADODB.Streamを使って検証してみようというオハナシです。

16進の[0x8FD9EA59]というデータをもったテキストファイルを作成し、ローカルに保存します。これをADODB.streamで読ませます。読ませるにあたって、バイナリではなくテキストモードとし、エンコードを、EUC-JPとして指定したり、Shift_JISとして指定したりして、読みこんだ結果、ADODB.streamがそれを、どんなUnicodeとして解釈しているかを見ようというわけです。

Shift_JISとして読ませますと次のようになります。
[0x8FD9EA59]を、[0x8FD9]+[0xEA59]として2バイトずつに区切って理解し、Shift_JISなので「詔」「鷓」に相当する文字のUnicodeとして、U+8A54 U+9DD3 の二文字分を出力します。

これは正しい挙動です。

EUC-JPとして読ませた場合に、期待される正解は次のようになります。
[0x8FD9EA59]を、[0x8FD9EA]+[0x59]として、3バイトと1バイトとに区切って理解し、EUC-JPなので、「薸」+「Y」に相当する文字のUnicodeとして、U+85B8 U+0059 の二文字分を出力します。

ADODB.streamは失敗します。上記のようになりません。 「傷」+「該」に相当する、U+50B7 U+8A72を出力します。

この変な挙動の仕組みにはShift_JISがひとやくかっていそうなのです。二段階に分裂したステップを踏んでいますので、順に書いてみます。

まず、第一段階目。
[0x8FD9EA59]を、[0x8F][0xD9EA][0x59]の3つに区切り、3文字分として解釈します。
ここで最初の一文字の処理をスキップします。二番目の文字[0xD9EA]を、EUC-JPと解して、このUnicodeを算出します。文字は、「搖」なので、U+6416 とします。

次に第二段階目。
U+6146は、Shift_JISにおいて、[0x9D8A]であることをADODB.streamは思い出します。第一段階で未処理であった、第一文字め[0x8F]と第三文字め[0x59]を忘れていたことに気がつくわけです。
そこで、[0x8F][0x9D8A][0x59]を改めて処理しようと決意するのですね。第二番目のコードがShift_JIS表現であることにご注意ください。
さらに狂気は進行します。
[0x8F][0x9D8A][0x59]を、[0x8F9D][0x8A59]の二文字ぶんであると解釈しなおします。そして、これらを、Shift_JISの文字であると思い込み、「傷」「該」として認知し、それぞれのUnicodeである、U+50B7 U+8A72 を出力します。

以上のように、EUC-JPとして解釈すべきところを失敗し、内部処理でShift_JISとして流してしまっていること、しかも2段階にわたる繰り返しの挙動をしているところが、不思議千万なところです。

なお、IE全体にわたって、同様にこの不可思議な挙動があります。

※というわけで今度こそ信じてください>長谷川検視官殿
  from 現場のいっかいの鑑識。これは殺人事件です。