exponenta event banner

CERT C: ERR30-C правил

Установите значение errno равным нулю перед вызовом библиотечной функции, известной для установки errno, и проверьте значение errno только после того, как функция вернет значение, указывающее на сбой

Описание

Определение правила

Установите значение errno равным нулю перед вызовом библиотечной функции, известной как errno, и проверьте значение errno только после того, как функция вернет значение, указывающее на сбой. [1 ]

Внедрение Polyspace

Эта проверка проверяет наличие следующих проблем:

  • Неправильное использование errno.

  • Errno не сбрасывается.

Примеры

развернуть все

Проблема

Неправильное использование errno происходит при проверке errno для условий ошибок в ситуациях, когда проверка errno не гарантирует отсутствие ошибок. В некоторых случаях проверка errno может привести к ложным срабатываниям.

Например, вы проверяете errno следующие вызовы функций:

  • fopen: Если следовать стандарту ISO ®, функция может не быть установленаerrno об ошибках.

  • atof: При соблюдении стандарта ISO функция не устанавливается errno.

  • signal: errno значение указывает на ошибку, только если функция возвращает SIG_ERR индикатор ошибки.

Риск

Стандарт ISO C не обеспечивает установку этих функций errno об ошибках. Установлены ли функции errno зависит или нет от реализации.

Обнаружение ошибок при проверке errno только действительность этой проверки также становится зависимой от реализации.

В некоторых случаях errno значение указывает на ошибку, только если функция возвращает определенный индикатор ошибки. Если проверить errno перед проверкой возвращаемого значения функции можно увидеть ложные положительные результаты.

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

Для получения информации об обнаружении ошибок см. документацию по данной функции.

Как правило, функции возвращают внеполосный индикатор ошибок для индикации ошибок. Например:

  • fopen возвращает нулевой указатель при возникновении ошибки.

  • signal возвращает значение SIG_ERR индикатор ошибок и наборы errno до положительного значения. Проверить errno только после проверки возвращаемого значения функции.

Пример - Неверная проверка errno После fopen Звонить
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define fatal_error() abort()

const char *temp_filename = "/tmp/demo.txt";

FILE *func()
{
    FILE *fileptr;
    errno = 0;
    fileptr = fopen(temp_filename, "w+b");
    if (errno != 0) {
        if (fileptr != NULL) {
            (void)fclose(fileptr);
        }
        /* Handle error */
        fatal_error();
    }
    return fileptr;
}

В этом примере: errno является первой переменной, которая проверяется после вызова fopen. Вы можете ожидать, что fopen изменения errno ненулевое значение при возникновении ошибки. При запуске этого кода с реализацией fopen который не установлен errno при возникновении ошибок может быть пропущено условие ошибки. В этой ситуации fopen может возвращать нулевой указатель, который скрывается от обнаружения.

Исправление - Проверка возвращаемого значения fopen После вызова

Одной из возможных корректировок является проверка только возвращаемого значения fopen для нулевого указателя.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>

#define fatal_error() abort()

const char *temp_filename = "/tmp/demo.txt";

FILE *func()
{
    FILE *fileptr;
    fileptr = fopen(temp_filename, "w+b");
    if (fileptr == NULL) { 
        fatal_error();
    }
    return fileptr;
}
Проблема

Errno not reset возникает, если не выполнить сброс errno перед вызовом функции, которая устанавливает errno для указания условий ошибки. Однако вы проверяете errno для этих ошибок после вызова функции.

Риск

errno не является чистым и может содержать значения из предыдущего вызова. Проверка errno для ошибок может создать ложное впечатление, что произошла ошибка.

errno устанавливается равным нулю при запуске программы, но впоследствии, errno не сбрасывается стандартной библиотечной функцией C. Необходимо явно задать errno до нуля при необходимости.

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

Перед вызовом функции, которая устанавливает errno для индикации ошибок, сброс errno до нуля явным образом.

Пример - errno Не сбрасывать перед вызовом strtod
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>

#define fatal_error() abort()

double func(const char *s1, const char *s2)
{
    double f1;
    f1 = strtod (s1, NULL);      
    if (0 == errno) {        
      double f2 = strtod (s2, NULL); 
        if (0 == errno) {        
            long double result = (long double)f1 + f2;
            if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) 
				  {
                return (double)result;
            }
        }
    }
    fatal_error();
    return 0.0;
}

В этом примере: errno не сбрасывается в 0 перед первым вызовом strtod. Проверка errno для 0 позже может привести к ложному положительному.

Коррекция - сброс errno Перед вызовом

Одной из возможных корректировок является сброс errno в 0 перед вызовом strtod.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <float.h>

#define fatal_error() abort()

double func(const char *s1, const char *s2)
{
    double f1;
    errno = 0;                   
    f1 = strtod (s1, NULL);
    if (0 == errno) {            
      double f2 = strtod (s2, NULL);  
        if (0 == errno) {       
            long double result = (long double)f1 + f2;
            if ((result <= (long double)DBL_MAX) && (result >= (long double)-DBL_MAX)) 
  			{
                return (double)result;
            }
        }
    }
    fatal_error();
    return 0.0;
}

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

Группа: Правило 12. Обработка ошибок (ERR)
Представлен в R2019a

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

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

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