CodeGuard detects access over run at vorbisenc.c

さて、前のエントリで「(ここは)動きました」と書いたのは、その先にさらなる罠があったからです。
alloca()の問題を解決することで、ようやくエンコードができるようになりました。
自分のテストプログラムでは、サンプリング周波数を11.025kHz→22.05kHz→44.1kHzの順に変えてテストしているのですが、22.05kHzのテスト中にCodeGuardがアクセスオーバーランを検知しました。

static void vorbis_encode_noisebias_setup(vorbis_info *vi,double s,int block,
                                         int *suppress,
                                         noise3 *in,
                                         noiseguard *guard,
                                         double userbias){
  int i,is=s,j;
  double ds=s-is;
  codec_setup_info *ci=vi->codec_setup;
  vorbis_info_psy *p=ci->psy_param[block];

  p->noisemaxsupp=suppress[is]*(1.-ds)+suppress[is+1]*ds;
  p->noisewindowlomin=guard[block].lo;

問題となっているのは、最後の行のguardです。
CodeGuard曰く、guardの配列のサイズが2なのにインデックス=2でアクセスしているとのこと。
guardの発生元を追っていくと、static変数_psy_noiseguards_8にたどり着きました。
CodeGuardの言っていることを確かめてみます。

if (guard == _psy_noiseguards_8)
    assert(block < sizeof(_psy_noiseguards_8)/sizeof(_psy_noiseguards_8[0]));

アウト!
Borlandだけでなく、VC++もアサートで止まります。
今度はlibvorbisのバグみたいです。
一旦テストケースから22kHzのテストをはずすことにします。
さてバグ報告、と。