AUTOSAR C++14 Rule A27-0-2

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

Описание

Управляйте определением

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

Объяснение

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

Реализация Polyspace

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

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

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

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

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

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

  • Целевое переполнение буфера в обработке строк.

    Эта проблема происходит, когда определенные функции манипуляции со струнами до пишут в свой целевой буферный аргумент при смещении, больше, чем 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