Home > Logs > August 2007 > This Entry
javascript における stack overflow
なぜか「stack overflow」というキーワードでいらっしゃる方が絶えないので、前回ちょっと苦労したときに調べて分かったことなんかを参考までに書いてみます。
stack overflow が発生する場合
まず、「stack overflow: line *」というアラートが出るのはIEのみですが、アラートが出るのが IE のみなだけで、原因が javascript のソースコードにあるのであれば、stack overflow 自体は javascript を処理することができるすべてのブラウザで発生します。
「stack overflow」の意味するところは、「処理中にメモリにデータを格納しきれずに溢れ出してしまいました」といったような意味です。一番簡単にこれを引き起こす例は以下です(文法的に、というかいろいろと間違っているので参考にはしないように)。
<input type="button" onclick="onclick()" />
あと、おかしなループ処理の場合にも発生します。例えば通常、ループ処理において回数をカウントする変数はローカル変数として宣言しますが、これをグローバル変数として宣言したりした場合において、ループ内で他の処理にカウント変数を渡し、そこで変数の内容を書き換えるなどの処理が行われると際限ないループに陥ったりしますが、このような場合にも「stack overflow」が発生する可能性があります。要は、一時格納メモリに処理データを保持しきれなくなった場合に起こるわけです。
解決策・回避策
解決策としては、ソースコードを見直す他にありません。逃げを打つこともできるのでしょうが、積極的な解決にはなりません。変数の宣言をチェックし、ライブラリを使っている場合はグローバル変数が競合していないか、引数として受け取ったデータが妥当なものか、また関数の使い方は正しいか、alert関数でデバッグプリントしながら地道に原因を探りましょう。
ただし、ソースコードの巨大なライブラリを使用している場合などは、かなり骨の折れる作業になる可能性があります。できるだけ javascript においては競合しないような変数(かつ短く、意味の伝わりやすい変数)を必要な間だけ使用し、できればライブラリにおける変数やその処理をチェックしておくことです。知識がない人はある人に聞きましょう。少なくとも公開する側、紹介する側に立つ場合はひととおりチェックしておくべきだと思います。
javascript だけで起こりうるものではない
ちなみに、「stack overflow」はメモリ管理に問題が発生した際に起こりうる事象なので、ブラウザでの javascript 処理に限らず、他のソフトでも発生します。C言語などにもこの概念は存在しますが、今はC言語専門ではないので言及は控えさせてください。ただ、プログラムが受け取ったデータの検証を行うように設計されていない場合、悪意のあるユーザーによって攻撃される可能性があります。あまり良い資料がみつからなかったのですが、社団法人ネットワークインフォメーションセンター内の脆弱性キーワードを読み解くという資料が参考になると思います。
要は、溢れたデータがメモリ領域の予期しない部分に書き込まれてしまう場合、悪意のあるユーザが自分の実行させたいプログラムを走らせるように、わざと overflow を発生させメモリ領域を書き換えるわけです。メモリ領域にはどの処理がどれかという情報が書き込まれているので、本来の処理を自分がさせたい処理に書き換えてしまえば、いろいろと悪いことができてしまう訳です。なのでプログラムにおいては、必ず受け取るパラメータの妥当性をチェックするようにする必要があります。
参考までに
FireFox の javascript 処理に関して脆弱性があることが発見されています。CNET Japan のCNET Japan: FirefoxのJavaScript実装に脆弱性--迅速な対応が困難な場合もという記事が簡潔にまとまっています。
ちなみに
あと、調べている途中に「ヤンデレ」という言葉があることを発見しました。こちらも非常に参考になると思います(stack overflow とは何の関係もありません)。
Post Comment