メインコンテンツ

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

CERT C: Rule FIO34-C

Distinguish between characters read from a file and EOF or WEOF

説明

ルール定義

ファイルから読み込んだ文字と EOF や WEOF を区別します。1

Polyspace 実装

ルール チェッカーは、"文字の値が EOF に吸収" をチェックします。

すべて展開する

問題

文字の値が EOF に吸収は、有効な文字値と EOF (ファイル終端) を区別できなくなるデータ型変換を実行する場合に発生します。Bug Finder は、次のいずれかの状態で欠陥にフラグを立てます。

  • ファイル終端: int から char への変換など、EOF ではない文字値を EOF に変換するデータ型変換を実行します。

    char ch = (char)getchar()
    次に、結果を EOF と比較します。
    if((int)ch == EOF)
    変換は明示的または暗黙的に行われる可能性があります。

  • ワイド文字のファイル終端: WEOF ではないワイド文字値を WEOF に変換するデータ型変換を実行後、結果を WEOF と比較します。

リスク

char データ型は、ファイル終端を示す値 EOF を保持することができません。getchar などの関数には、EOF に対応するために、戻り値の int 型があります。int から char に変換すると、値 UCHAR_MAX (有効な文字値) と EOF はどちらも値 -1 に変換され、相互に区別できなくなります。この変換結果を EOF と比較すると、EOF の誤検知につながる可能性があります。この原理は、ワイド文字の値と WEOF にも当てはまります。

修正方法

EOF または WEOF との比較を変換前に実行します。

例 - char に変換される getchar の戻り値
#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

char func(void)
{
    char ch;
    ch = getchar();
    if (EOF == (int)ch) { //Noncompliant
        fatal_error();
    }
    return ch;
}

この例では、getchar の戻り値が char に暗黙的に変換されます。getcharUCHAR_MAX を返す場合、-1 に変換され、EOF と区別できません。その後 EOF と比較すると、誤検知につながる可能性があります。

修正 — 変換前に EOF との比較を実行

1 つの修正方法として、最初に EOF との比較を実行後、int から char に変換します。

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

char func(void)
{
    int i;               
    i = getchar();       
    if (EOF == i) {      
        fatal_error();
    }
    else {
        return (char)i;
    }
}

チェック情報

グループ: Rule 09.入出力 (FIO)

バージョン履歴

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.