Возможно, что-то не так (с точки зрения безопасности программного обеспечения) с этим фрагментом кода, и я не могу понять это ... Функция die завершает программу после отображения строкового аргумента.
void get_user(char* user) { char buf[1024]; if (strlen(user) > sizeof(buf)) die("error: user string too long\n"); strcpy(buf, user); … }
-thx!
Если strlen(user) равно 1024, strcpy запишет один байт после конца buf.
strlen(user)
strcpy
buf
Не учитывается терминатор NUL (\0) для строки.
\0
if (strlen(user) >= sizeof(buf))
Небезопасно, если user имеет 1024 символа (будет записывать 0 где-нибудь в стеке).
user
0
Проблема здесь:
if (strlen(user) > sizeof(buf))
это не учитывает нулевой терминатор, когда strlen(user) == sizeof( buf ). Чек должен быть
strlen(user) == sizeof( buf )
if (strlen(user) > sizeof(buf) - 1 )
, чтобы strcpy() мог постоянно копировать нулевой терминатор.
strcpy()
Есть ошибка, которая может привести к переполнению буфера.Помните, что strlen дает вам количество символов в строке, исключая нулевой терминатор.Чек должен быть:
if (strlen(user) + 1 > sizeof(buf))
Из man-страницы strlen:
Функция strlen () вычисляет длину строки s, не включая завершающий символ '\ 0'.
ииз man-страницы strcpy:
Функция strcpy () копирует строку, на которую указывает src, включая завершающий нулевой байт ('\ 0'), в буфер, на который указывает dest.
Несоответствие при сравнении размеров.Код проверяет, меньше ли длина строки, чем буфер, но копирует длину строки +1 символ.Если длина строки (без завершающего '\ 0') равна 1024, происходит переполнение.
Ответ связан с количеством копий символов strcpy по сравнению с количеством возвращаемых символов chr.
Подсказка: strcpy , strlen