sprintf 使用時の変数化けについて - KBA203916 - Community Translated (JA)

Version 1

    Community Translated by  Motoo Tanaka        Version: **

     

    Translation - English:  Variable Corruption when Using sprintf - KBA203916

     

    質問:

    sprintf を使用して文字配列に文字列を代入しているときに、他の特定の変数が化けることに気が付きました。この原因は何で、どのようにしたら防ぐことが出来るのでしょうか?

     

    回答:

    sprintf は変換後の文字列をポインタで示された始めの場所 (sprintf 関数の引数としてわたされたもの) から最後の場所 "始めの場所 + 文字列の長さ + 1" に保存します。追加されている1文字は文字列の終端をしめす NULL(ヌル)文字です。その為、もしこの長さがそれを保存するために宣言された配列の大きさを超えていた場合、メモリ上で文字列を保存するために宣言された配列よりも後に置かれている変数を破壊(上書き)してしまう可能性があります。

     

    例えば、下記のようなコードを考えてください:

     

    char str[10] ;

    sprintf(str, "SamplePrint") ;

     

    このコードは結果の 12 バイト (11バイトの実際の文字と1バイトの終端を示す NULL 文字) を str[0] のアドレスから始まるメモリに保存します。コンパイラは 11番目と 12番目のアドレスに他の変数を割り当てているかも知れません。そのため、11番目のアドレスと 12番目のアドレスに置かれてる変数は、この sprintf コールによって破壊 (上書き) されてしまうかも知れません。この問題を防ぐためには、結果を保存する文字配列が保存される文字列全体とNULL文字を保存するのに充分な大きさであることを確認する必要があります。

    この例では、str を 12 以上の大きさで宣言していれば問題は回避されます。

     

    ※これはセキュリティに影響を与える可能性もありますので、現在は書き込まれる文字列の長さを制限する snprint() の使用が推奨されています。