メインコンテンツ

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

CERT C++: STR34-C

Cast characters to unsigned char before converting to larger integer sizes

説明

ルール定義

文字をより大きい整数サイズに変換する前に、符号なし char にキャストします。1

Polyspace 実装

ルール チェッカーは、"符号拡張文字の値の不適切な使用" をチェックします。

すべて展開する

問題

符号拡張文字の値の不適切な使用は、符号付きまたはプレーンな char データ型を、符号拡張を伴ってより大きな整数データ型に変換する場合に発生します。その後、符号拡張された変換後の値を、EOF との比較のために配列インデックスとして使用したり、文字処理関数の引数として使用したりします。

リスク

EOF との比較: コンパイラがプレーンな char 型を符号付きとして実装するとします。この実装では、10 進数形式で 255 (2 の補数形式では -1) である文字が符号付きの値として格納されます。たとえば、char 型の変数をより大きなデータ型 int に変換すると、符号ビットが保持されます (符号拡張)。この符号拡張により 10 進数形式で 255 である文字が整数 -1 に変換されるため、EOF と区別することはできません。

配列インデックスとして使用: 同じ理由から、符号拡張されたプレーンな char 型の変数は配列インデックスとして使用できません。符号ビットが保持されると、char から int への変換で負の整数になる可能性があります。配列インデックスには正の整数値を使用しなければなりません。

文字処理関数の引数: 同じ理由から、符号拡張されたプレーンな char 型の変数は、isalpha()isdigit() など、ctype.h で宣言されている文字処理関数の引数として使用できません。C11 規格 (節 7.4) によると、unsigned char または EOF として表現できない整数引数を指定した場合、結果の動作は未定義になります。

修正方法

より大きな整数データ型に変換する前に、符号付きまたはプレーンな char 値を明示的に unsigned char にキャストします。

例 - 符号拡張文字の値と EOF の比較
#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

extern char parsed_token_buffer[20];

static int parser(char *buf)
{
    int c = EOF;
    if (buf && *buf) {
        c = *buf++;    
    }
    return c;
}

void func()
{
    if (parser(parsed_token_buffer) == EOF) {  //Noncompliant
        /* Handle error */
        fatal_error();
    }
}

この例では、関数 parser によって文字列入力 buf を走査できます。文字列内の文字が 10 進数形式で 255 の場合、それを int 型の変数 c に変換すると、その値は -1 になり、EOF と区別できなくなります。その後の EOF との比較は、誤検知につながる可能性があります。

修正 — 変換前に unsigned char にキャスト

1 つの修正方法として、より大きな int 型に変換する前に、プレーンな char 型の値を unsigned char にキャストします。

#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

extern char parsed_token_buffer[20];

static int parser(char *buf)
{
    int c = EOF;
    if (buf && *buf) {
        c = (unsigned char)*buf++;    
    }
    return c;
}

void func()
{
    if (parser(parsed_token_buffer) == EOF) { 
        /* Handle error */
        fatal_error();
    }
}

チェック情報

グループ: 05.文字と文字列 (STR)

バージョン履歴

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.