Akihiro YAMANOI
a.yam****@gmail*****
2008年 2月 29日 (金) 13:18:24 JST
山野井です。 sen_snip_open()関数のバグ報告です。Senna-1.1.1で追加された SEN_SNIP_COPY_TAGフラグを指定した際の挙動に関してです。 [発生した環境] ・CPU: VIA C3 ・メモリ容量: 512MB ・ハードディスク容量: 160GB(空き100GB) ・OS: CentOS4.4 ・uname -aの結果: Linux localhost.localdomain 2.6.9-42.0.10.EL #1 Tue Feb 27 09:24:42 EST 2007 i686 i686 i386 GNU/Linux ・Senna: 1.1.1 ・gcc: 3.4.6 [起こっている問題] sen_snip_open()関数は、flags引数にSEN_SNIP_COPY_TAGフラグを指定しても defaultopentag及びdefaultclosetagを複製せずに保持します。 (lib/snip.c:388行目辺り) しかし、sen_snip_close()関数は、SEN_SNIP_COPY_TAGフラグが立っている場合 保持しているdefaultopentag及びdefaultclosetagに対しSEN_FREE()を呼びます。 (lib/snip.c:432行目辺り) 上記が原因で、senna外部で確保した変数が意図せず解放されてしまいます。 [再現方法1] char *openTag = calloc(9, sizeof(char)); memcpy(openTag, "<strong>", 8); openTag[8] = '\0'; sen_snip *snip = sen_snip_open( sen_enc_utf8, SEN_SNIP_COPY_TAG, 100, 1, openTag, strlen(openTag), NULL, 0, NULL ); sen_snip_close(snip); free(openTag); ---- (実行結果) セグメンテーション違反です。 ---- と表示されました。呼び出し側で確保した文字列変数openTagが sen_snip_close()内部で解放されてしまい、呼び出し側のfree()は エラーになります。 [再現方法2] char *openTag = calloc(9, sizeof(char)); memcpy(openTag, "<strong>", 8); openTag[8] = '\0'; sen_snip *snip = sen_snip_open( sen_enc_utf8, SEN_SNIP_COPY_TAG, 100, 1, openTag, strlen(openTag), openTag, strlen(openTag), /* 同じ変数を与える */ NULL ); sen_snip_close(snip); ---- (実行結果) *** glibc detected *** double free or corruption (fasttop): 0x0a5b8c48 *** アボートしました ---- と表示されました。sen_snip_close()内部でopenTag変数が2重に 解放されてエラーが発生します。 sen_snip_close()にデフォルトタグ文字列の解放処理が記述されていましたので、 sen_snip_open()内で文字列を複製していないのは不具合なのではと思い、ご報告 させて頂きました。 バグではなく仕様上あえてこうなっていましたら、上記報告は私の勘違いです! ご確認頂けると嬉しいです。 よろしくお願いいたします。