メインコンテンツ

MISRA C:2012 Rule 21.18

The size_t argument passed to any function in <string.h> shall have an appropriate value

説明

ルール定義

The size_t argument passed to any function in <string.h> shall have an appropriate value. 1

This rule comes from MISRA C™:2012 Amendment 1.

根拠

<string.h> で定義された関数に渡される size_t 引数の値は、正の値で、かつ、関数にポインター渡しされる最小オブジェクトのサイズ以下の値にする必要があります。strncmp() 関数を使用して文字列 str1str2 を比較する、次のコードについて考えます。

strncmp(lhs_string, rhs_string, num)
size_t 引数の num は、正の値で、かつ、str1str2 のうちの小さいほうのサイズ以下にする必要があります。

そうしない場合、この関数を使用すると、関数引数の範囲外への読み取りまたは書き込みアクセスが行われる可能性があります。

Polyspace 実装

メモリ関数または文字列関数を <string.h> から呼び出すと、関数引数の範囲外の読み取りまたは書き込みアクセスが行われる場合、Polyspace® は違反を報告します。以下に例を示します。

  • メモリ関数または文字列関数の引数が null で終了しないバッファーであり、サイズ パラメーターに渡された値が少なくとも 1 つのバッファーのサイズよりも大きい場合、違反が報告されます。次のコードについて考えます。

    char buf1[ 3 ] = "abc";
    char buf2[ 6 ] = "123456";
    (void) memcpy(buf2, buf1, 5); // Violation
    (void) memcpy(buf1, buf2, 4); // Violation
    memcpy() の呼び出しにより、buf1 の範囲外のメモリ位置への書き込みアクセスが行われます。

  • メモリ関数または文字列関数の引数が、null で終了するバッファーまたは C 文字列であり、コピー先の文字列がソース文字列よりも小さい場合、コピー先の文字列のサイズよりも大きい値をサイズ引数に渡すと、違反が報告されます。次のコードについて考えます。

    char str1[] = "abc";
    char str2[] = "123456";
    (void) strncpy(str1, str2, 5); // Violation
    str2 から str1 に 5 文字をコピーすると、str1 の範囲外のメモリ位置への書き込みアクセスが行われます。null で終了するバッファーまたは C 文字列の場合は、サイズ引数にかかわらず、コピー先の文字列がソース文字列より大きくても、違反は報告されません。

メモリ関数または文字列関数が <string.h> から呼び出される場合、Polyspace はこのルールの違反をチェックします。チェック対象の関数には、memchr()memcmp()memcpy()memmove()memset()strncat()strncmp()strncpy()strxfrm() が含まれます。これらの関数が呼び出される時点で引数バッファーまたは文字列のサイズが未知の場合、Polyspace は違反を報告しません。

トラブルシューティング

ルール違反を想定していてもその違反が表示されない場合、コーディング規約違反が想定どおりに表示されない理由の診断を参照します。

すべて展開する

#include <string.h>
char buf1[ 5 ] = "12345";
char buf2[ 10 ] = "1234567890";

void f(void)
{
    if (memcmp(buf1, buf2, 5) == 0) {    /* Compliant */

    }
    if (memcmp(buf1, buf2, 6) == 0) {    /* Non-compliant */

    }
}

この例では、最初の if ステートメントはこのルールに準拠しています。これは、buf2 の最初の 5 つの要素を buf1 にコピーしても、これらのバッファーの範囲外への読み取りまたは書き込みアクセスが行われないためです。

2 番目の if ステートメントはこのルールに準拠していません。これは、サイズ引数の値は 6 で、コピー先のバッファー buf1 のサイズよりも大きいためです。この memcmp() の呼び出しにより、buf1 の範囲外への書き込みアクセスが行われます。

チェック情報

グループ: 標準ライブラリ
カテゴリ: Mandatory
AGC カテゴリ: Mandatory

バージョン履歴

R2017a で導入


1 All MISRA coding rules and directives are © Copyright The MISRA Consortium Limited 2021.

The MISRA coding standards referenced in the Polyspace Bug Finder™ documentation are from the following MISRA standards:

  • MISRA C:2004

  • MISRA C:2012

  • MISRA C:2023

  • MISRA C++:2008

  • MISRA C++:2023

MISRA and MISRA C are registered trademarks of The MISRA Consortium Limited 2021.