以下のコードは、「format.hpp」にある、二進表記関数だ。
しかし、致命的なバグがある・・
void out_bin_(int32_t v) { char* p = &buff_[sizeof(buff_) - 1]; *p = 0; uint8_t n = 0; do { --p; *p = (v & 1) + '0'; v >>= 1; ++n; } while(v != 0) ; out_str_(p, 0, n); }
バグの存在に気がついただろうか?
引数「v」が「負」の場合、「v」の右シフトは、符号が消えない為、「0」判定が正常
に機能しない為無限ループとなり、配列を超えて不正なアクセスが起こる。
※通常、プログラムはクラッシュするだろう・・
void out_bin_(uint32_t v) {
それで、上記のように、関数の引数を「int32_t」から「uint32_t」にすれば解決する。
「format.hpp」は、以前に、かなり広範囲にチェックしていたが、テストケースが抜けて
いた。
十分チェックしたつもりで、頑丈だと思っていたので、こんな危険なバグがあった事はショ
ックだが、仕方ない、よりよいテストを行う事と、危険な橋を避ける必要があるようだ。
format による二進表現は現在まであまり使わなかったので、この大きなバグによる弊害は
無かったが、危ない瞬間だった・・