Доступ к буферу выходит за границы в cppcheck

Код может быть скомпилирован, и результат в порядке. Но cppcheck сообщит об ошибке.

#define BUF_SIZE     1024
#define MAX_LENG     80

static unsigned char path[MAX_LENG];
unsigned char file_buf[BUF_SIZE*2];

memset(file_buf, 0, sizeof(file_buf));
strcpy(file_buf, "KID ");
strncat(file_buf, &path[strlen(path)-12], 10); //error this line

Я пробовал несколько раз, и до сих пор не могу найти причину. Кто-нибудь может дать мне несколько советов?

Спасибо всем за ответы.

но у меня есть еще вопросы: если это фатальная ошибка, почему компилятор прошел и результат такой, какой я хочу? При каком условии у него будут проблемы?

Есть ли альтернативный способ реализовать это?

И если бы я изменил его на

strncat(file_buf, &path[strlen(path)-12], 5);

ошибка cppcheack исчезнет. Почему?


person BigDongle    schedule 13.12.2018    source источник


Ответы (2)


Вот этот буфер:

static unsigned char path[MAX_LENG];

Является статическим и, следовательно, инициализируется нулем. Первый символ равен 0 при первом выполнении этого кода. Таким образом, strlen(path) собирается вернуть (size_t)0. Вычтите из этого 12, и вы получите очень большое беззнаковое число из-за модульной арифметики, число, которое определенно больше, чем 1024.

person StoryTeller - Unslander Monica    schedule 13.12.2018

Вы обращаетесь к массиву со слишком большим индексом:

static unsigned char path[MAX_LENG];

Будучи static, он инициализируется нулями. Это означает, что strlen(path) вернет 0.

strncat(file_buf, &path[strlen(path)-12], 10);

Здесь вы вычитаете 12, что будет -12, но поскольку strlen возвращает беззнаковое значение, результирующий индекс равен SIZE_MAX-12, что явно выходит за пределы.

person Gerhardh    schedule 13.12.2018
comment
@MM Поскольку числовой круг фактический индекс равен -12, если strlen возвращает ноль. Допустимые индексы массива — положительные числа, но на самом деле это доступ перед массивом. - person harper; 13.12.2018
comment
@harper нет, это не так. - person M.M; 13.12.2018