6

Microsoft のstrncat. ソース バッファを超えて 1 バイトに達します。次のコードを検討してください。

#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>

void main()
{
    char dstBuf[1024];
    char* src = malloc(112);
    memset(src, 'a', 112);
    dstBuf[0] = 0;
    strncat(dstBuf, src, 112);
}

strncat112 バイト ブロックの後に 1 バイトを読み取ります。そのため、不運にも無効なページ境界に割り当てられると、アプリケーションがクラッシュします。大規模なアプリケーションは、そのような場所で断続的にクラッシュする可能性があります。(このような状態は、 gflags PageHeap設定でシミュレートできることに注意してください。適切な位置合わせのために、ブロック サイズはポインター サイズで割り切れる必要があります。)

これは予想される動作ですか、それともバグですか? それを確認するリンクはありますか?(いくつかの説明を読みstrncatましたが、最初の心構えに応じて両方の方法で解釈できます...)

更新(証拠に関する質問に答えるために):上記のテキストから明らかでない場合は申し訳ありませんが、これは実験的な事実です. strncatアドレス src+srcBufSize の読み取り時に、アプリケーションで断続的なクラッシュが発生します。この小さな例では、クラッシュ時にgflags PageHeapを使用して実行すると、一貫して (100%) 再現されます。私が見る限り、証拠は非常にしっかりしています。

Update2 (コンパイラに関する情報) MS Visual Studio 2005 バージョン 8.0.50727.867。ビルド プラットフォーム: 64 ビット リリース (32 ビットの再現なし)。クラッシュの再現に使用された OS: Windows Server 2008 R2。

Update 3この問題は、MS Visual Studio 2012 11.0.50727.1 でビルドされたバイナリでも再現されます。

Update 4 Microsoft Connect の問題へのリンクMSDN フォーラムのディスカッションへのリンク

Update 5この問題は、次の VS リリースで修正される予定です。古いバージョンの修正は予定されていません。上記の「Microsoft Connect」リンクを参照してください。

4

3 に答える 3

3

状態のドキュメントstrncat:

src - コピー元のヌル終了バイト文字列へのポインター

srcしたがって、実装では、入力パラメーターが文字よりも長い場合でも、実際には NUL で終了していると見なすことができますcount

さらに確認するために、Microsoft のドキュメントには次のように記載されています。

strSource

NULL で終わるソース文字列。

一方、実際の C 標準では次のように規定されています。

このstrncat関数は、 が指す配列から が指す文字列の末尾に までの文字を追加nします (ヌル文字とそれに続く文字は追加されません) 。s2s1

以下のコメントで指摘されているように、これは 2 番目のパラメーターs2配列として識別し、NUL で終了する文字列ではありません。ただし、このドキュメントはs1から読み取るときの関数の動作ではなく、に対する最終的な影響を説明しているため、これは元の質問に関してはまだあいまいs2です。

これはもちろん、C ランタイム ライブラリのソース コードを参照することで、特定の Microsoft 実装に関して解決できます。

于 2013-08-30T03:48:23.490 に答える