このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
CWE Rule 685
説明
ルールの説明
The software calls a function, procedure, or routine, but the caller specifies too many arguments, or too few arguments, which may lead to undefined behavior and resultant weaknesses.
Polyspace 実装
ルール チェッカーは以下の問題をチェックします。
書式文字列指定子と引数の不一致
現在の引数リストに対する va_arg 呼び出しが多すぎます
関数ポインターの信頼性の低いキャスト
例
この問題は、printf
などの書式設定付き出力関数内の書式指定子が、それに対応する引数と一致しない場合に発生します。たとえば、unsigned long
型の引数の書式指定は %lu
でなければなりません。
書式指定子と対応する引数の間の不一致により、未定義の動作が発生します。
書式指定子が対応する引数と一致することを確認します。たとえば、次の例では、%d
指定子は文字列引数 message
に一致せず、%s
指定子は整数引数 err_number
に一致しません。
const char *message = "License not available";
int err_number = ;-4
printf("Error: %d (error type %s)\n", message, err_number);
認識される引数のデータ型が整数プロモーションによって変更された場合、解析結果に元の型とプロモーション後の型の両方が示されます。書式指定子は整数プロモーション後の型と一致していなければなりません。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処(Polyspace ユーザー インターフェイスで結果をレビューする場合)
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access)(Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
#include <stdio.h>
void string_format(void) {
unsigned long fst = 1;
printf("%d\n", fst); //Noncompliant
}
printf
ステートメントで、書式指定子 %d
が fst
のデータ型と一致していません。
1 つの修正方法として、%lu
書式指定子を使用することができます。この指定子は fst
の unsigned
整数型および long
サイズに合致します。
#include <stdio.h>
void string_format(void) {
unsigned long fst = 1;
printf("%lu\n", fst);
}
1 つの修正方法として、書式指定子と一致するように引数を変更することができます。fst
を書式指定子と一致するよう整数に変換し、値 1
を出力します。
#include <stdio.h>
void string_format(void) {
unsigned long fst = 1;
printf("%d\n", (int)fst);
}
この問題は、va_arg
の呼び出しの数が、対応する可変個引数関数に渡される引数の数を超えている場合に発生します。解析では、可変個引数関数が呼び出される場合にのみ欠陥が報告されます。
[現在の引数リストに対する va_arg 呼び出しが多すぎます] では、次の場合には欠陥を報告しません。
可変個引数関数内の
va_arg
の呼び出しの数が不確定である。たとえば、呼び出しが外部ソースからのものである場合です。va_arg
で使用されるva_list
が無効である。
va_arg
を呼び出すとき、va_list
内に使用可能な次の引数がないと、動作が未定義になります。va_arg
の呼び出しによって、データが破損したり、予期しない結果が返されたりする可能性があります。
適切な数の引数を可変個引数関数に渡すようにします。
#include <stdarg.h>
#include <stddef.h>
#include <math.h>
/* variadic function defined with
* one named argument 'count'
*/
int variadic_func(int count, ...) {
int result = -1;
va_list ap;
va_start(ap, count);
if (count > 0) {
result = va_arg(ap, int);
count --;
if (count > 0) {
/* No further argument available
* in va_list when calling va_arg
*/
result += va_arg(ap, int); //Noncompliant
}
}
va_end(ap);
return result;
}
void func(void) {
(void)variadic_func(2, 100);
}
この例では、func()
内で呼び出されたときに、名前付き引数と可変個引数が 1 つだけ variadic_func()
に渡されます。va_arg
の 2 番目の呼び出しでは、ap
で使用可能な可変個引数がそれ以上ないため、動作が未定義になります。
1 つの修正方法として、適切な数の引数を可変個引数関数に渡すようにします。
#include <stdarg.h>
#include <stddef.h>
#include <math.h>
/* variadic function defined with
* one named argument 'count'
*/
int variadic_func(int count, ...) {
int result = -1;
va_list ap;
va_start(ap, count);
if (count > 0) {
result = va_arg(ap, int);
count --;
if (count > 0) {
/* The correct number of arguments is
* passed to va_list when variadic_func()
* is called inside func()
*/
result += va_arg(ap, int);
}
}
va_end(ap);
return result;
}
void func(void) {
(void)variadic_func(2, 100, 200);
}
この問題は、関数ポインターが、引数または戻り値の型が異なる別の関数ポインターにキャストされた場合に発生します。
関数ポインターを引数または戻り値の型が異なる別の関数ポインターにキャストし、後者の関数ポインターを使用して関数を呼び出した場合、動作は未定義になります。
引数または戻り値の型が一致しない 2 つの関数ポインター間のキャストは避けます。
以下の修正例を参照してください。
問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処(Polyspace ユーザー インターフェイスで結果をレビューする場合)
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access)(Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
#include <stdio.h>
#include <math.h>
#define PI 3.142
double Calculate_Sum(int (*fptr)(double))
{
double sum = 0.0;
double y;
for (int i = 0; i <= 100; i++)
{
y = (*fptr)(i*PI/100);
sum += y;
}
return sum / 100;
}
int main(void)
{
double (*fp)(double);
double sum;
fp = sin;
sum = Calculate_Sum(fp); //Noncompliant
/* Defect: fp implicitly cast to int(*) (double) */
printf("sum(sin): %f\n", sum);
return 0;
}
関数ポインター fp
は double (*)(double)
として宣言されています。しかし、関数 Calculate_Sum
に渡す時に fp
は暗黙的に int (*)(double)
にキャストされます。
1 つの修正方法として、Calculate_Sum
の定義における関数ポインターが、fp
と同じ引数および戻り値の型をもつことをチェックすることができます。このステップにより、fp
が異なる引数または戻り値の型に暗黙的にキャストされないことが保証されます。
#include <stdio.h>
#include <math.h>
# define PI 3.142
/*Fix: fptr has same argument and return type everywhere*/
double Calculate_Sum(double (*fptr)(double))
{
double sum = 0.0;
double y;
for (int i = 0; i <= 100; i++)
{
y = (*fptr)(i*PI/100);
sum += y;
}
return sum / 100;
}
int main(void)
{
double (*fp)(double);
double sum;
fp = sin;
sum = Calculate_Sum(fp);
printf("sum(sin): %f\n", sum);
return 0;
}
チェック情報
カテゴリ: その他 |
バージョン履歴
R2023a で導入
MATLAB Command
You clicked a link that corresponds to this MATLAB command:
Run the command by entering it in the MATLAB Command Window. Web browsers do not support MATLAB commands.
Web サイトの選択
Web サイトを選択すると、翻訳されたコンテンツにアクセスし、地域のイベントやサービスを確認できます。現在の位置情報に基づき、次のサイトの選択を推奨します:
また、以下のリストから Web サイトを選択することもできます。
最適なサイトパフォーマンスの取得方法
中国のサイト (中国語または英語) を選択することで、最適なサイトパフォーマンスが得られます。その他の国の MathWorks のサイトは、お客様の地域からのアクセスが最適化されていません。
南北アメリカ
- América Latina (Español)
- Canada (English)
- United States (English)
ヨーロッパ
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)