メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

CWE Rule 20

Improper Input Validation

R2024a 以降

説明

ルールの説明

The product receives input or data, but it does not validate or incorrectly validates that the input has the properties that are required to process the data safely and correctly.

Polyspace 実装

ルール チェッカーは、[文字列から数値への変換は安全ではありません] をチェックします。

すべて展開する

問題

この問題は、文字列から整数または浮動小数点値への変換が行われ、その変換メソッドにロバストなエラー処理が含まれていなかった場合に発生します。

リスク

文字列を数値に変換すると、データの損失や誤った解釈の原因となる場合があります。変換の検証またはエラー処理がないと、プロクラムは無効な値を使って続行されます。

修正方法
  • 数値を検証する新たなチェックを追加します。

  • strtolstrtollstrtoulstrtoull などの、文字列から数値へのよりロバストな変換関数を使用します。

例 — atoi による変換
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

static int demo_check_string_not_empty(char *s)
{
    if (s != NULL)
        return strlen(s) > 0; /* check string null-terminated and not empty */
    else
        return 0;
}

int unsafestrtonumeric(char* argv1)
{
    int s = 0;
    if (demo_check_string_not_empty(argv1))
    {
        s = atoi(argv1);  //Noncompliant
    }
    return s;
}

この例では、atoi を使って argv1 を整数に変換しています。atoi では無効な整数の文字列についてのエラーが提供されません。この変換は予期せず失敗する可能性があります。

修正 — 代わりに strtol を使用

考えられる 1 つの修正方法として、strtol を使用して入力文字列と変換後の整数を検証します。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <errno.h>

static int demo_check_string_not_empty(char *s)
{
    if (s != NULL)
        return strlen(s) > 0; /* check string null-terminated and not empty */
    else
        return 0;
}

int unsafestrtonumeric(char *argv1)
{
    char *c_str = argv1;
    char *end;
    long sl;

    if (demo_check_string_not_empty(c_str))
    {
        errno = 0; /* set errno for error check */
        sl = strtol(c_str, &end, 10);
        if (end == c_str)
        {
            (void)fprintf(stderr, "%s: not a decimal number\n", c_str);
        }
        else if ('\0' != *end)
        {
            (void)fprintf(stderr, "%s: extra characters: %s\n", c_str, end);
        }
        else if ((LONG_MIN == sl || LONG_MAX == sl) && ERANGE == errno)
        {
            (void)fprintf(stderr, "%s out of range of type long\n", c_str);
        }
        else if (sl > INT_MAX)
        {
            (void)fprintf(stderr, "%ld greater than INT_MAX\n", sl);
        }
        else if (sl < INT_MIN)
        {
            (void)fprintf(stderr, "%ld less than INT_MIN\n", sl);
        }
        else
        {
            return (int)sl;
        }
    }
    return 0;
}

チェック情報

カテゴリ: その他

バージョン履歴

R2024a で導入