メインコンテンツ

標準関数が不適切な引数で呼び出されました

標準関数の引数がその関数における使用の要件を満たさない

説明

この欠陥は、特定の標準関数の引数が、その関数における使用の要件を満たしていない場合に発生します。

たとえば、こうした関数の引数は次のような形で無効になることがあります。

関数の種類状態リスク修正方法
strlenstrcpy のような文字列操作関数ポインター引数が NULL 終端文字列を指さない。関数の動作が未定義になる。NULL 終端文字列を文字列操作関数に渡す。
fputcfread のような、stdio.h 内のファイル処理関数FILE* ポインター引数が値 NULL をもつことがある。関数の動作が未定義になる。FILE* ポインターを関数の引数として使用する前に、NULL についてテストする。
lseekread のような、unistd.h 内のファイル処理関数 ファイル記述子の引数が -1 になることがある。

関数の動作が未定義になる。

関数 open のほとんどの実装で、ファイル記述子の値として -1 が返される。また、errno が設定され、ファイルを開く際にエラーが発生したことを示す。

関数 open の戻り値を、readlseek の引数として使用する前に、-1 についてテストする。

戻り値が -1 であれば、errno の値をチェックして、どのエラーが発生したのかを確認する。

ファイル記述子の引数が、閉じられたファイル記述子を表している。関数の動作が未定義になる。ファイル記述子は、その使用が完全に終了してから閉じる。あるいは、ファイル記述子を関数の引数として使用する前に再度開く。
mkdtempmkstemps のようなディレクトリ名生成関数文字列テンプレートの最後の 6 文字が XXXXXX でない。関数により、最後の 6 文字が、ファイル名を一意にする文字列で置き換えられる。最後の 6 文字が XXXXXX でない場合、関数は十分な一意性をもつディレクトリ名を生成できない。文字列を関数の引数として使用する前に、その文字列の最後の 6 文字が XXXXXX であるかどうかをテストする。
getenvsetenv のような、環境変数に関連した関数文字列引数が "" である。動作が処理系定義になる。文字列引数を getenvsetenv の引数として使用する前に、"" についてテストする。
文字列引数が等号 = で終了している。たとえば、"C" ではなく "C=" になっている。動作が処理系定義になる。文字列引数を = で終わりにしない。
strtokstrstr のような文字列処理関数

  • strtok: 区切り記号引数が "" である。

  • strstr: 検索文字列引数が "" である。

実装によっては、こうしたエッジ ケースが扱われない。文字列を関数の引数として使用する前に、"" についてテストする。

修正方法

修正方法は欠陥の根本原因によって異なります。上の表に記載されている修正と以下の修正付きのコード例を参照してください。

問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。

すべて展開する

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

enum {
    SIZE10 = 10,
    SIZE20 = 20
};

int func() {
    char* s = NULL;
    return strnlen(s, SIZE20);
}

この例では、NULL ポインターが strnlen の引数として、NULL 終端文字列の代わりに渡されています。

コードの解析を実行する前に、GNU® コンパイラを指定します。コンパイラ (-compiler)を参照してください。

修正 — NULL 終端文字列を渡す

NULL 終端文字列を、strnlen の最初の引数として渡します。

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

enum {
    SIZE10 = 10,
    SIZE20 = 20
};

int func() {
    char* s = "";
    return strnlen(s, SIZE20);
}

結果情報

グループ: プログラミング
言語: C | C++
既定値: 手書きコードはオン、生成コードはオフ
コマンド ライン構文: STD_FUNC_ARG_MISMATCH
影響度: Medium

バージョン履歴

R2015b で導入