gets
— функция, входящая в Стандартную библиотеку языка Си, объявляемая в заголовочном файле stdio.h
, которая считывает строку стандартного ввода и помещает её в буфер, созданный вызывающей функцией. Если выдаёт ошибку, то теперь для её вызова следует использовать gets_s.
Программист должен знать максимум числа символов, которые должны быть считаны gets
, чтобы удостовериться, что выделяется буфер достаточного размера. Подобное невозможно без информации о данных. Эта проблема может приводить к созданию ошибок и открывает простор для нарушений компьютерной безопасности при помощи переполнения буфера. Многие источники советуют программистам никогда не использовать gets
в новых программах[1][2][3].
Применение gets
весьма осуждается. Функция оставлена в стандартах C89 и C99 для обратной совместимости. Множество инструментов разработки ПО, как, например, GNU ld, выдаёт предупреждения в случае обнаружения при компоновке кода с использованием gets
.
Вместо gets
могут быть использованы другие функции строкового ввода, что позволит избежать ошибок, связанных с переполнением буфера. Простейшим вариантом будет fgets
. При замене кода вида
нужно иметь в виду, что вызов fgets(buffer, sizeof buffer, stdin)
отличается от gets(buffer)
не только защитой от переполнения буфера, но и тем, что fgets(buffer, sizeof buffer, stdin)
сохраняет завершающий символ перевода строки (если ввод линии заканчивается символом перевода строки), в то время как gets(buffer)
отбрасывает его.
Безопасное использование gets
требует от программиста проверки того, что переполнение буфера не станет проблемой. Стандарт языка Си этого не гарантирует; тем не менее, существует несколько относительно усложненных способов проверки этого с различной степенью переносимости. Одним из возможных вариантов является защитная страница для защиты памяти. В сочетании с обработчиками исключений, такими как SIGSEGV
и sigaction
, защитная страница может помочь с обработкой ошибок.