Предотвращение переполнения буфера с помощью

Объявление gets:

char * gets ( char * str );

Обратите внимание на вопиющее упущение максимального размера для str.

cplusplus.com говорит 2

Обратите внимание, что получение отличается от fgets: не только использует stdin как источник, но он не включает символ окончания строки в полученной строке и не позволяет указать максимальный размер для str (, что может привести к переполнению буфера).

А также:

Самая последняя версия стандарта C (2011) окончательно удалил эту функцию из ее спецификации. Функция устаревший в С++ (по состоянию на 2011 год, который следует за C99 + TC3).

Теперь, конечно, fgets обычно рекомендуется в качестве замены gets, потому что его объявление выглядит следующим образом:

char * fgets ( char * str, int num, FILE * stream );

Он ДАЕТ принять параметр размера. Это делает его намного безопаснее, чем gets.

Теперь, поскольку я не хочу тратить деньги на скачивание или покупку C11 standard, может ли кто-нибудь пролить свет на причину обесценивания gets и что это значит для будущего кода? Почему он существует в том же месте, когда fgets безопаснее? И почему он только сейчас устарел?

Ответ 1

gets устарел, поскольку он небезопасен, как вы уже цитировали, это может вызвать переполнение буфера. Для замены C11 предоставляет альтернативу gets_s с такой подписью:

char *gets_s(char *s, rsize_t n);

Обратите внимание, что C11 по-прежнему рекомендует fgets заменить gets.

В самом деле, ставит ли стандарт gets в противоречие, но Комитет решил, что gets полезен, когда программист имеет адекватный контроль над вводом.

Здесь официальное разъяснение Комитета.

Обоснование для международного стандарта - Языки программирования C §7.19.7.7 Функция gets:

Поскольку gets не проверяет переполнение буфера, обычно его небезопасно использовать, когда его вход не находится под контролем программистов. Это заставило некоторых допросить, должно ли оно вообще появляться в Стандарте. Комитет решил, что gets был полезен и удобен в тех особых обстоятельствах, когда программист действительно имеет адекватный контроль над исходными данными и как многолетняя существующая практика, ему нужна стандартная спецификация. В общем, однако, предпочтительная функция fgets (см. П. 7.19.7.2).

Ответ 2

Теперь, поскольку я не хочу тратить деньги на скачивание или покупку стандарта C11, может ли кто-нибудь пролить свет на причину обескураживания и что это означает для будущего кода?

Из комитета C в C99 Обоснование:

Поскольку gets не проверяет переполнение буфера, обычно его небезопасно использовать, когда его вход не находится под контролем программистов. Это заставило некоторых допросить, должно ли оно вообще появляться в Стандарте. Комитет решил, что получение было полезным и удобным в тех особых обстоятельствах, когда у программиста есть достаточный контроль над исходными данными, и как многолетняя существующая практика, ему нужна стандартная спецификация. В целом, однако, предпочтительной функцией является fgets.