HSPコンパイラのSEGVを修正してコミットしました
色々調べてみて分かったんですけど、
- Endless macro loop エラーが出なかったのは単に macloop が 1000 に達するより早く SEGV が起こっていたから。
- b %1の%1がなければ落ちなかったのはただの文字数の問題。
だったことが分かりました。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
で、 token.cpp を追っていてあることに気づきました。
- C と HSP のマクロ展開には決定的な違いがある。
それはマクロ定義内のマクロをいつ展開するかです。 C ではマクロを定義する時点で定義の中のマクロを展開しているように見えます。だから、 HSP みたいにマクロの巡回で無限ループが起こったりはしないんです。一方 HSP ではマクロが展開されたときにその定義の中のマクロも展開します。
たとえば、次のスクリプト。
#define B return #define A B A
これは、Aが展開されてBに書き換わる→Bが展開されてreturnに書き換わる→returnが展開されてreturn@hspに書き換わる→おわり、というように展開されるんですね。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
ちなみにエンドレスループエラーは「1行のうちにポインタが進まなかった回数が1000以上になる」と起こります。
#define b mes #define a b a:a:a:a:a:a:a:a:a:a:a:a:a:a:a:a: (333回ぐらい以上?a:がつづく)
だから、こんなふうにマクロが巡回していなくてもエラーを起こすことができます。
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
で、 SEGV なんですが。ざっとみても文字列長が大きいと SEGV がおきそうなところが結構あるんですね;ランタイムの SEGV よりかはコンパイラの SEGV は多少寛容であっていいとは思うけど。。。
うーん、オーバーランの可能性が十分に残っているプログラムをサーバーで動かすのはやめたほうがいいのかなあ?悪意ある投稿で任意のコードが実行されてしまったりとか。まあ、別に狙われて攻撃されたりとかはなさそうだから大丈夫?