JPCERT コーディネーションセンター

FIO40-C. fgets() が失敗したときは引数に渡した配列の内容をリセットする

C99 によれば、fgets() 関数が読み取りに失敗すると、引数に渡した配列の内容は不定となる。したがって、それ以降に呼び出す文字列操作関数でエラーが発生するのを避けるために、配列の内容を既知の値にリセットしなければならない。

fgetws() 関数にも同様の問題がある。

違反コード

以下のコード例では、fgets() が読み取りに失敗するとエラーフラグを設定する。

char buf[BUFSIZ];
FILE *file;
/* file を初期化する */

if (fgets(buf, sizeof(buf), file) == NULL) {
  /* エラーフラグを設定し、処理を続行する */
}

しかし、buf はリセットされておらず、その内容は不定である。

適合コード

以下の解決法では、fgets が読み取りに失敗した場合 buf は空の文字列に設定される。fgetws() の場合も同様に、buf に空のワイド文字列を設定することで問題を解決できる。

char buf[BUFSIZ];
FILE *file;
/* file を初期化する */

if (fgets(buf, sizeof(buf), file) == NULL) {
  /* エラーフラグを設定し、処理を続行する */
  *buf = '\0';
}
例外

FIO40-EX1: fgets()fgetws() を呼び出した直後に配列がスコープ外になる場合や、読み取りに失敗した後に配列が参照されないのであれば、配列の内容をリセットする必要はない。

リスク評価

fgetsfgetws() が変更する配列の内容について誤った想定をすると、未定義の動作が発生したりプログラムが異常終了する可能性がある。

ルール 深刻度 可能性 修正コスト 優先度 レベル
FIO40-C P4 L3
参考情報
翻訳元

これは以下のページを翻訳したものです。

FIO40-C. Reset strings on fgets() failure

Top へ

Topへ
最新情報(RSSメーリングリストTwitter