まずこの記事はChrome最新版に基づくものです。その他のブラウザの情報や検証結果などありましたらコメントいただけるとありがたいです。
今回の無限アラートがブラクラだとして、不安を煽るような記事が多数存在しており、もちろんエンジニアなら簡単にわかることですが、その会社の影響なのかブラクラだと勘違いする人が自分の観測範囲に多くいたので、なぜブラクラではないのか技術的な観点から検証していきたいと思います。
まずブラクラ(ブラウザクラッシャー)は広い意味で使われているので、齟齬が無いようにこの記事内での言葉通りブラクラはブラウザをクラッシュさせるものだと定義します。実際にブラウザがクラッシュする他に著しく不安定になったり、正規の方法で閉じれなくなるようなこともクラッシュに含め、ブラウザのバグに起因するものは除外するとします。
無限アラートがブラクラではないことを検証する前に、ブラクラがどんな物なのか理解しやすいようにブラクラとされてきたものをいくつか見ていきましょう。比較するためにソースを載せますが、実行する際は必ず自己責任でお願いします。
実際のブラクラ
無限ループ
何もしないただの無限ループです。しかし何もしないというのは1回のループに時間がかからないことになり、短時間で大量の繰り返しが発生し無限に繰り返されます。あっという間にChromeが管理するCPU使用率が100%近くになりました。Chromeが不安定になりタブは閉じられませんしページの反応もありません。Chromeのタスクマネージャで実行したタブを強制終了することで終了できました。
while (true);
JavaScriptでは非同期性を実現するために、1つの処理が終わってからキューにある次の処理を実行していくイベントループというシステムというものがあり、スクリプトの実行以外にも描画を含めたページ全体の処理がイベントループ上に実装されています。しかし無限ループは処理が永遠に終わらないので、イベントループ自体をブロックしてしまいます。
※ちなみに一時期はGIFアニメーションですら、無限ループによってブロックされていました。(今は確認できていません)
無限に新しいページを開く
無限に新しいページを開く処理です。上記の無限ループの問題点に加えて新しいページが開かれるというコストがあるかと思いきや、2回目以降のwindow.open()
はChromeによってブロックされるので1つしか新しいページは開かれません。しかし無限ループが止まるわけではないので上記の問題は顕在です。
while (true) window.open()
※ウィンドウが開かれていく状況を重視してあえて時間を開けているものもありましたね(今Chromeではどれも動きませんが...)
無限アラート
実際のブラクラを軽く見たところで、今回の無限アラートを見てみましょう。
while (true)
と無限ループが入っていて、上記の無限ループの問題点を含むように一瞬思いますが、実際はalert()
もアラートが閉じられるまで処理がブロックされるので、一回閉じるごとに1回しかループが発生しません。閉じたときに一回だけループされますが、数十ミリ秒で連続して何百個も閉じれば変わってきますが、とても現実的ではないので負荷という観点からしたら問題はなさそうです。
while (true) alert('!')
本題とは少しそれますが、ブラクラに続いて言われる問題として、アラートが絶え間なく表示されることが上げられるので、それについても見てみましょう。
確かに上に書いた通りアラートはページ全体の処理を止めてしまうのでページの操作ができなくなります。しかしChromeではアラートが表示されていても、ウィンドウや、URLバー、メニュー、戻るボタン、タブの×ボタンや、ショートカットまで、ページ内以外は通常通り操作でき、タブの×ボタンから通常通りタブを閉じれます。
終わりに
ということで、無限アラートはブラウザをクラッシュさせませんし、操作に支障もきたしません。つまりブラクラではないことがわかりました。
最後に僕はなにかある度に便乗してプログラムを有害だとしてユーザーの不安を煽り、世論をミスリードする記事を書く記者や、セキュリティソフト会社に反対します!そしてそんな会社によってCoinhive事件の被害者にされたモロさんには健闘を祈ります。