Руководство по GNU
Эта цитата взята из руководства по GNU
Предупреждение: если входные данные имеют нулевой символ, вы не можете сказать.Так что не используйте fgets, если вы не знаете, что данные не могут содержать ноль.Не используйте его для чтения файлов, отредактированных пользователем, потому что, если пользователь вставляет нулевой символ, вы должны либо обработать его правильно, либо распечатать четкое сообщение об ошибке.Мы рекомендуем использовать getline вместо fgets.
Как обычно, я потратил время на поиск, прежде чем задавать вопрос, и нашел такой же вопрос о переполнении стека пять лет назад: Почемуфункция fgets устарела?
Хотя GNU рекомендует getline
вместо fgets
, я заметил, что getline
в stdio.h
занимает строку любого размера.Он вызывает realloc
по мере необходимости.Если я попытаюсь установить размер 10 символов:
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buffer;
size_t bufsize = 10;
size_t characters;
buffer = (char *)malloc(bufsize * sizeof(char));
if( buffer == NULL)
{
perror("Unable to allocate buffer");
exit(1);
}
printf("Type something: ");
characters = getline(&buffer,&bufsize,stdin);
printf("%zu characters were read.\n",characters);
printf("You typed: '%s'\n",buffer);
return(0);
}
В приведенном выше коде введите строку любого размера, более 10 символов, и getline прочитает ее и даст правильный вывод.
Нет необходимости даже malloc
, как я делал в коде выше - getline
сделает это за вас.Я устанавливаю размер буфера 0, и getline
будет malloc
и realloc
для меня по мере необходимости.
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *buffer;
size_t bufsize = 0;
size_t characters;
printf("Type something: ");
characters = getline(&buffer,&bufsize,stdin);
printf("%zu characters were read.\n",characters);
printf("You typed: '%s'\n",buffer);
return(0);
}
Если вы запустите этот код, снова вы можете ввести строку любого размера,и это работает.Несмотря на то, что я установил размер буфера равным 0.
Я искал методы безопасного кодирования из рекомендаций CERT www.securecoding.cert.org
Я думалпереключения с fgets
на getline
, но проблема, с которой я сталкиваюсь, заключается в том, что я не могу понять, как ограничить ввод в getline
.Я думаю, что злоумышленник может использовать цикл для отправки неограниченного объема данных и использовать все оперативные памяти, доступные в куче?
Есть ли способ ограничения размера ввода, который используется getline
или getline
имеет некоторое ограничение в функции?