Был ли get когда-нибудь полезен?

Мне кажется, люди, особенно изучающие язык программирования C, все еще используют gets< /a> для чтения данных из стандартного ввода. Несмотря на это, теперь он был удален1 из стандарта C11, а отказ от ответственности на cppreference гласит:

Функция gets() не выполняет проверку границ, поэтому эта функция чрезвычайно уязвима для атак переполнения буфера. Его нельзя использовать безопасно (если только программа не работает в среде, которая ограничивает то, что может отображаться на стандартном вводе). По этой причине эта функция объявлена ​​устаревшей в третьем исправлении к стандарту C99 и полностью удалена в стандарте C11. fgets() и gets_s() являются рекомендуемой заменой.

Никогда не используйте get().

Однако похоже, что это не новая проблема, возникшая в связи с более современными философиями программирования. Он всегда был бы сломан и вызывал сбой программ, и я не понимаю, что можно было бы подразумевать под «средой, которая ограничивает то, что может отображаться на стандартном вводе».

Итак, было ли это когда-либо полезным в прошлом? Или по какой причине он был добавлен в предыдущие стандарты и достандартные версии C?


(1) ... или, по крайней мере, изменено, чтобы иметь дополнительный параметр, указывающий максимальную длину для чтения. Однако я спрашиваю о старой подписи, получая только указатель.


person bitmask    schedule 05.03.2013    source источник
comment
Из Часто задаваемых вопросов Вы должны задавать только практические вопросы, на которые можно ответить, основанные на реальных проблемах, с которыми вы сталкиваетесь.. . (выделено мной).   -  person T.J. Crowder    schedule 05.03.2013
comment
???? stackoverflow.com/questions/3302255/c- scanf-vs-gets-vs-fgets   -  person Joe DF    schedule 05.03.2013
comment
@T.J.Crowder - в нем также говорится о проблемах, уникальных для профессии программирования, вы бы не стали спрашивать об использовании API за пределами профессии программирования.   -  person Mike    schedule 05.03.2013
comment
@Mike: Да, но я применяю && к этим критериям. Кажется, вы применяете ||. :-) Здесь нет реальной проблемы. Я не устанавливал правила SO (и это было бы другое место, если бы я это сделал), я просто указываю на них.   -  person T.J. Crowder    schedule 05.03.2013
comment
@T.J.Crowder Подстрекательская настойчивость gets среди начинающих является реальной проблемой, с которой мы все сталкиваемся, поэтому я не понимаю ни вашей точки зрения, ни вашего VTC.   -  person bitmask    schedule 05.03.2013
comment
@bitmask: Дальнейший вопрос об этом не изменит этого. И с этого момента я приступаю к настоящей работе. :-) (Не какая-то лажа, у меня есть вызов конф, на который мне нужно попасть... Так что, может быть, не настоящая работа...)   -  person T.J. Crowder    schedule 05.03.2013
comment
среда, которая ограничивает то, что может отображаться на стандартном вводе, означает, что парень, использующий терминал, знает, что он не может ввести больше, чем то, что он думает/предполагает, является размером массива символов, используемым в программе...   -  person Barath Ravikumar    schedule 05.03.2013
comment
Возможно, лучше было бы сформулировать вопрос так: для чего gets практично? В настоящее время невозможно ответить без определения полезности и, вероятно, вызовет дебаты, аргументы или расширенное обсуждение. Если вы хотите, чтобы вопрос был открыт повторно, ответ на него должен быть фактическим.   -  person Paul Turner    schedule 05.03.2013
comment
@Tragedian: Спасибо за ваш отзыв (я очень ценю, если люди дают конструктивные комментарии по близким причинам). Но что влечет за собой ваше различие между полезным и практическим?   -  person bitmask    schedule 05.03.2013


Ответы (4)


Да, это было полезно и в то же время «чрезвычайно уязвимо для атак переполнения буфера».

Он всегда был бы сломан и вызывал сбой программ, и я не понимаю, что можно было бы подразумевать под «средой, которая ограничивает то, что может отображаться на стандартном вводе».

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

Также см. этот вопрос: Почему получает функцию настолько опасную, что ее нельзя использовать?

person lbalazscs    schedule 05.03.2013
comment
Как неявно указано в ОП, это противоречия. Если я подвергаю свою программу переполнению буфера, вызывая gets, то это определенно бесполезно. Вопрос спрашивает, были ли раньше дополнительные меры безопасности, а если нет, то почему gets было определено именно так. - person bitmask; 05.03.2013
comment
@bitmask Для меня полезно означает, что это может помочь реализовать некоторые полезные функции для пользователя. Программа может быть полезной и небезопасной одновременно... - person lbalazscs; 05.03.2013
comment
C был разработан в 70-х годах. Тогда сетевые системы были скорее исключением, чем нормой, и безопасность не считалась столь важной, как сегодня. Данные обычно считались такими же надежными, как и программное обеспечение. - person Philipp; 05.03.2013
comment
Я уверен, что gets вызовет сбой программ с гораздо большей вероятностью, чем вызовет проблемы с безопасностью (которые должны быть тщательно изготовлены). - person Aki Suihkonen; 05.03.2013
comment
Я даже не говорю о безопасности (как замечает Аки). Особенно для языка системного программирования сбои имеют катастрофические последствия и совершенно не связаны с безопасностью. - person bitmask; 05.03.2013
comment
@bitmask Ну, может быть, вы не думаете о безопасности, но приведенная вами цитата явно говорит об атаках с переполнением буфера. - person lbalazscs; 05.03.2013
comment
+1 за первое предложение, хотя, честно говоря, это утверждение можно применить ко всему C. :-) - person T.E.D.; 05.03.2013

Когда вы смотрите на остатки ранних дней C, вы должны учитывать исторический фон.

Язык C был разработан в 70-х годах. Тогда сетевые системы были скорее исключением, чем нормой, и безопасность не считалась столь важной, как сегодня. Системы редко работали с ненадежными сторонними данными. И даже когда они это делали, это не считалось таким уж большим риском. Информационные технологии все еще находились в зачаточном состоянии. Никто не понимал, насколько чувствительными могут быть компьютерные системы.

Процессорное время, с другой стороны, было драгоценным. Программы должны быть максимально эффективными.

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

Но сегодня, в 21 веке, когда все компьютерные системы взаимосвязаны, все компьютерные системы постоянно обрабатывают информацию из ненадежных или даже неизвестных источников, а хакерство — это индустрия с оборотом в миллиарды долларов, безопасность стала приоритетом номер один для каждой компьютерной программы.

person Philipp    schedule 05.03.2013
comment
Я говорил не о безопасности в сегодняшнем понимании, а о надежности. Но ваш аргумент в пользу скорости — очень хороший аргумент, который мог бы иметь приоритет над как безопасностью, так и надежностью. - person bitmask; 05.03.2013

Когда был изобретен gets, очень немногим программам требовалось принимать большие объемы данных из ненадежных источников. gets подходит для ограниченного ввода от сотрудничающего пользователя. Этот пользователь обеспечивает «среду, которая ограничивает то, что может появиться», не вводя много текста в каждой строке. Вы можете в значительной степени рассчитывать на то, что пользователь, сидящий за терминалом, не будет вводить сотни байтов данных в приглашение «y/n». Если они передали большой файл в вашу программу, когда ваша программа не была предназначена для этого, что ж, они получили плохие результаты.

Программы, которым приходилось обрабатывать произвольный ввод, не использовали gets.

В настоящее время злонамеренный ввод данных является обычным явлением на практике и наносит еще больший ущерб, поскольку существуют инструменты и методы, позволяющие злоумышленникам легко использовать переполнение буфера в своих интересах. Хорошо обученный пользователь, печатающий по подсказке, — это нишевый случай. Кроме того, учет злонамеренного ввода данных широко используется как хороший метод, обеспечивающий устойчивость программного обеспечения к неожиданным вводам, которые не были предназначены для атаки. Ожидается, что почти все программы будут обрабатывать произвольный ввод. Так что gets явно неадекватно.

person Steve Jessop    schedule 05.03.2013

Gets по-прежнему полезен для прототипирования. Это быстро пишется и дает ожидаемые результаты для программиста, который ориентирован на решение текущей проблемы, а не на то, чтобы его или ее программа дала сбой.

person Aki Suihkonen    schedule 05.03.2013
comment
fgets действительно так же быстро пишет. Предоставление размера буфера и стандартного входного файла FILE не является таким большим препятствием. - person bitmask; 05.03.2013
comment
@bitmask: раздражает необходимость использовать strlen для поиска новой строки, чтобы ее можно было удалить. - person supercat; 28.03.2015