AUTOSAR C++14 Rule A27-0-2

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

Описание

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

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

Объяснение

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

Реализация Polyspace

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

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

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

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

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

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

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

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

    Например, при вызове функции 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