メインコンテンツ

ISO/IEC TS 17961 [chreof]

EOF と区別できない文字値の使用

説明

ルール定義

EOF と区別できない文字値の使用。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) {
        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;
    }
}

チェック情報

決定可能性:決定不可能

バージョン履歴

R2019a で導入


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.