exponenta event banner

Правило AUTOSAR C++ 14 A27-0-2

Строка в стиле C должна гарантировать достаточное пространство для данных и нулевого терминатора

Описание

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

Строка в стиле C должна гарантировать достаточное пространство для данных и нулевого терминатора.

Объяснение

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

Внедрение Polyspace

Средство проверки ищет следующие проблемы:

  • Использование опасной стандартной функции.

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

    Более полный список функций и их более безопасных альтернатив см. в разделе Use of dangerous standard function.

  • Переполнение буфера из неверного спецификатора формата строки.

    Эта проблема возникает, когда аргумент спецификатора формата для функций C, таких как sscanf приводит к переполнению или занижению в аргументе буфера памяти.

  • Переполнение буфера назначения при обработке строк.

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

    Например, при вызове функции sprintf(char* buffer, const char* format), используется постоянная строка format большего размера, чем buffer.

Поиск неисправностей

Если вы ожидаете нарушения правила, но не видите его, обратитесь к разделу Нарушения стандартов кодирования не отображаются.

Примеры

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

#include <cstdio>
#include <cstring>

#define BUFF_SIZE 128


int noncompliant_func(char *str) {
    char dst[BUFF_SIZE];
    int r = 0;

    if (sprintf(dst, "%s", str) == 1) { //Noncompliant
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}

int compliant_func(char *str) {
    char dst[BUFF_SIZE];
    int r = 0;

    if (snprintf(dst, sizeof(dst), "%s", str) == 1) { //Compliant
        r += 1;
        dst[BUFF_SIZE-1] = '\0';
    }
    
    return r;
}

В этом примере правило нарушается при использовании sprintf функция, которая не позволяет управлять длиной записываемых данных. Чтобы избежать возможного переполнения буфера, используйте более безопасную альтернативную функцию snprintf.

#include <cstdio>

void noncompliant_func (char *str[]) {
    char buf[32];
    sscanf(str[1], "%33c", buf); //Noncompliant
}

void compliant_func (char *str[]) {
    char buf[32];
    sscanf(str[1], "%32c", buf); //Compliant
}

В этом примере буфер buf может содержать 32 char элементы. Поэтому спецификатор формата %33c вызывает переполнение буфера и нарушает правило. Чтобы избежать нарушения правила, считывайте в буфер меньшее количество элементов.

#include <cstdio>

void noncompliant_func(void) {
    char buf[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";

    sprintf(buf, fmt_string); //Noncompliant
}

void compliant_func(void) {
    char buf[20];
    char *fmt_string = "This is a very long string, it does not fit in the buffer";

    snprintf(buf, 20, fmt_string); //Compliant
}

В этом примере буфер buf может содержать 20 char элементы. Следовательно, чем больше размер fmt_string вызывает переполнение буфера и нарушает правило. Чтобы избежать нарушения правила, используйте snprintf для обеспечения контроля длины и считывания в буфер менее 20 элементов.

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

Группа: Библиотека ввода/вывода
Категория: Консультации, Автоматизированные
Представлен в R2020b