先日は徳丸浩さんによる PHP5.3.7 の crypt 関数におけるバグの解説を読み、世界的に有名なオープンソースソフトウェアでもこんな初歩的なミスをやらかすのかとすごく親近感が湧いてしまったが、Pau Garcia Quiles が語るこれまでで最も愚かしい C のバグとは何か?
彼はテンポラリファイルを tmpfile() で作る Unix アプリケーションの移植をやっていた。
else if (code == 200) { // Downloading whole file /* Write new file (plus allow reading once we finish) */ g = fname ? fopen(fname, "w+") : tmpfile(); }
マイクロソフトの tmpfile() の実装ではテンポラリファイルは C ドライブ直下に作成される。この手の名前は同じだが Unix と Windows で流儀が違う関数の挙動に苦しむことが多かったので、これを忘れないようコメントを入れた。
else if (code == 200) { // Downloading whole file /* Write new file (plus allow reading once we finish) */ // FIXME Win32 native version fails here because Microsoft's version of tmpfile() creates the file in C:\ g = fname ? fopen(fname, "w+") : tmpfile(); }
この後も話は続くのだが、実はこの時点で彼はとんでもないバグを仕込んでしまっていた。バグといってもコメントを入れただけなのに? 何がバグかお分かりだろうか?
そう、C ドライブ直下を示すコメントの最後にバックスラッシュがあるため、改行が無視され、次の行の処理自体コメントの一部と見なされてしまうのだ!
確かにマクロを定義するときにこの改行を無視させるバックスラッシュを使って複数行にコードを展開し見やすくする手法をよく使うが、こんなところでしかもコメントの中でそれが発動してしまうとは思わないよな。
ネタ元は Hacker News。