火曜日, 9月 29, 2015

Chromeで「http://a/%%30%30」を検索してはいけない

Chromeがこの16文字でクラッシュする理由

(今Chrome使用中の人は、この下のリンクをマウスオーバするだけでクラッシュしてしまうので要注意!)
Chromeはhttp://a/%%30%30と入力するだけでクラッシュします。マウスオーバだとタブがクラッシュするだけですけど、今試しに「http://a/%%30%30」とアドレスバーにコピペして検索ボタンを押したら…本当にプログラム強制終了になっちゃいました。あー自動保存されてて良かった…ふぅ…!

どうしてこんなことに? Tom Scottさんが動画で解説してますよ。

[動画の抄訳]
コンピュータはあらゆるデータを0と1のバイナリで保存してるよね。だらだらとどこまでも0と1が並んでるだけだ。そんな状態で、URLのはじまりと終わりをどう見分けるのか? 最初のは「h」で見つかるが、どこまで続くのかがわからない。だから「h」の前のコードで「この下の何桁ですよ」と予告してやるのさ。


150924binary.jpg
こんな風に。

ただものすごく長い場合もあるので、これはいろんなアプローチがあるのだけど、例えばおしまいのところに「00000000」のNULLってやつをつけてやるのもそのひとつ。これがいわゆる「ヌル・ターミネイティッド・ストリング(ヌル文字で終わる文字列)」だ。'90年代からある古い手で今でも使われている。

150924binary_b.jpg
0が8つ並んでNULL。

さて、「http://a/%%30%30」の何が問題なのか? スペースサインは数字2桁と組み合わせると、ほかの文字に変換されるっていうのがあって、この「%30」は「0」に変換される。

150924binary_c.jpg

すると最後の「%30%30」が「00」に置き換えられる。ところがその前にもう1個「%」があるよね? 合体すると「」で「NULL」とイコールになっちゃうのだ!

150924binary_d.jpg
=NULL

「ははーん、あってはならない場所にNULLがあるから、それでいきなり終わるのね」という単純な話でもない。Chromeは全文字列をひとつの文字列として解釈して1回デコードする。するとエスケープ抜きの「http://a/」で、有効なURLとして認識される。で、そのまま送るんだけど、その先で「」はエスケープされ無効なURLと認識され、ほんでぶつかり合ってクラッシュ、ということね。


Chris Mills - Gizmodo US[原文