CERT C: Rule FIO34-C

Различие между символами, считанными из файла, и EOF или 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 иметь тип возврата int для размещения EOF. Если вы преобразовываете из int на char, значения UCHAR_MAX (допустимое значение символа) и EOF преобразуется в одно и то же значение -1 и становится неотличимым друг от друга. Когда вы сравниваете результат этого преобразования с EOFсравнение может привести к ложному обнаружению EOF. Это обоснование также относится к широким значениям символов и WEOF.

Зафиксировать

Сравнение выполните с EOF или WEOF перед преобразованием.

Пример - Возвращаемое значение getchar Преобразовано в char
#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. Если getchar возвращает UCHAR_MAX, преобразуется в -1, что неотличимо от EOF. Когда вы сравниваете с EOF позже, это может привести к ложному положению.

Коррекция - выполните сравнение с EOF перед преобразованием

Одной из возможных коррекций является то, чтобы сначала выполнить сравнение с 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;
    }
}

Проверяйте информацию

Группа: Правило 09. Входной выход (FIO)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.