Webkit の Bugzilla で強烈なバグが報告されていると、同僚に教えて頂いた。
あまり話題になっていないものの、単純ゆえに強烈なバグだと思ったので Qiita にも公開しておく。
https://bugs.webkit.org/show_bug.cgi?id=151354 にそのバグ報告が上がっている。
最初に Google+ でやりとり があった模様。
URL のクエリ文字列から値を取り出す関数が正常に動作していないことから発覚したようだ。
その後は、簡単なテストケースに落とし込まれ jsfiddle というサイトにテストケースが公開されている。
Safari でこのページを開くと、実際に JavaScript を実行して確認できるようになっている。
続報 (2015.12.14)
この記事を上げてすぐに Bugzilla の方で進展があった。 Yusuke SUZUKI さんが原因を特定し、パッチを投稿なさっている。 (本当にありがとうございます。) 今のところのチェンジセットは http://trac.webkit.org/changeset/194021 で確認することができる。 どうしてこのような挙動になるのかも詳細に記載されている。 2015 年12月14日現在、 Webkit Nightly ではこの時の修正も取り込まれている r194029 のビルドが公開されている。 私もダウンロードして試してみたところ、 r194029 では再現しなかった。めでたい。 Safari でも未来のアップデートのいずれかのタイミングで再現しなくなるのだろう。実際の動作
オブジェクトのキー"1"に対応する値を取り出す超シンプルな関数
function getOne(a) { return a['1']; }
この関数に対して
getOne({1: true})
普通に考えれば true を返却する。
しかし、実際には
getOne({2: true})
のような (これは undefined を返す) 無関係の引数で36回以上呼び出すと、
なぜか getOne({1: true})
までも undefined を返却するように、挙動が変わってしまう。
↓ は私の Mac OS X 上の Safari で確認したもの。なるほど確かに36回 getOne({2: true})
を実行した以降、 undefined が返るようになってしまっている。