メインコンテンツ

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

CERT C: Rule EXP40-C

Do not modify constant objects

説明

ルール定義

定数オブジェクトを変更しないようにします。1

Polyspace 実装

ルール チェッカーは、"定数制限付きオブジェクトに書き込んでいます" をチェックします。

すべて展開する

問題

const で修飾されたオブジェクトに書き込んでいますは、次のいずれかが行われる場合に発生します。

  • const 修飾子付きのオブジェクトを代入先として使用する。

  • const 修飾子付きのオブジェクトを、引数を変更する関数に渡す。

たとえば、この欠陥は次のような状態で発生します。

  • const 修飾子付きのオブジェクトが、次に挙げるいずれかの関数で最初の引数として渡されている。

    • mkstemp

    • mkostemp

    • mkostemps

    • mkdtemp

  • const 修飾子付きのオブジェクトが、次に挙げるいずれかの関数の適用先引数として渡されている。

    • strcpy

    • strncpy

    • strcat

    • memset

  • const 修飾子付きのオブジェクトに対し、書き込み操作が実行されている。

リスク

リスクは、const 修飾子付きオブジェクトに対する変更内容によって異なります。

状態リスク
mkstempmkostempmkostempsmkdtemp などに渡すこれらの関数では、最初の引数の最後の 6 文字が文字列に置き換えられる。したがって、変更可能な char 配列が最初の引数として必要とされる。
strcpystrncpystrcatmemset などに渡すこれらの関数では、適用先引数が変更される。したがって、変更可能な char 配列が適用先引数として必要とされる。
オブジェクトへの書き込みconst 修飾子には、そのオブジェクトの値は変更されないという取り決めが含意されている。const 修飾子付きのオブジェクトへの書き込みは、その取り決めに違反する。操作の結果は未定義となる。
修正方法

修正方法は、const 修飾子付きオブジェクトに対する変更内容によって異なります。

状態修正方法
mkstempmkostempmkostempsmkdtemp などに渡す関数の最初の引数として、非 const オブジェクトを渡す。
strcpystrncpystrcatmemset などに渡す関数の適用先引数として、非 const オブジェクトを渡す。
オブジェクトへの書き込み書き込み操作を、非 const オブジェクトに対して実行する。

以下の修正例を参照してください。

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

例 - const 修飾子付きオブジェクトへの書き込み
#include <string.h>

const char* buffer = "abcdeXXXXXXX";

void func(char* string) {
    char *ptr = (char*)strchr(buffer,'X');
    if(ptr)
        strcpy(ptr,string); //Noncompliant
}

この例では、bufferconst で修飾されているため、strchr(buffer,'X')const で修飾された char* ポインターを返します。この char* ポインターが strcpy の適用先引数として使用されると、エラー [定数制限付きオブジェクトに書き込んでいます] が発生します。

修正 — const 修飾子付きのオブジェクトを非 const オブジェクトにコピー

1 つの修正方法として、定数文字列を非 const オブジェクトに代入し、その非 const オブジェクトを strchr の適用先引数として使用します。

#include <string.h>

char buffer[] = "abcdeXXXXXXX";

void func(char* string) { 
    char *ptr = (char*)strchr(buffer,'X');
    if(ptr)
        strcpy(ptr,string);
}

チェック情報

グループ: Rule 03.式 (EXP)

バージョン履歴

R2019a で導入


1 This software has been created by MathWorks incorporating portions of: the “SEI CERT-C Website,” © 2017 Carnegie Mellon University, the SEI CERT-C++ Web site © 2017 Carnegie Mellon University, ”SEI CERT C Coding Standard – Rules for Developing safe, Reliable and Secure systems – 2016 Edition,” © 2016 Carnegie Mellon University, and “SEI CERT C++ Coding Standard – Rules for Developing safe, Reliable and Secure systems in C++ – 2016 Edition” © 2016 Carnegie Mellon University, with special permission from its Software Engineering Institute.

ANY MATERIAL OF CARNEGIE MELLON UNIVERSITY AND/OR ITS SOFTWARE ENGINEERING INSTITUTE CONTAINED HEREIN IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.

This software and associated documentation has not been reviewed nor is it endorsed by Carnegie Mellon University or its Software Engineering Institute.