- gets
-
gets— функция, входящая в Стандартную библиотеку языка Си, объявляемая в заголовочном файлеstdio.h, которая считывает строку стандартного ввода и помещает ее в буфер, созданный вызывающей функцией.Содержание
Реализация
Может быть реализована следующим способом (при помощи
getchar):char *gets(char *s) { int i, k = getchar(); /* Возвращаем NULL если ничего не введено */ if (k == EOF) return NULL; /* Считываем и копируем в буфер символы пока не достигнем конца строки или файла */ for (i = 0; k != EOF && k != '\n'; ++i) { s[i] = k; k = getchar(); /* При обнаружении ошибки результирующий буфер непригоден */ if (k == EOF && !feof(stdin)) return NULL; } /* Нуль-терминируем и возвращаем буфер в случае успеха. Символ перевода строки в буфере не хранится. */ s[i] = '\0'; return s; }
Программист должен знать максимум числа символов, которые должны быть считаны
gets, чтобы удостовериться, что выделяется буфер достаточного размера. Подобное невозможно без информации о данных. Эта проблема может приводить к созданию ошибок и открывает простор для нарушений компьютерной безопасности при помощи переполнения буфера. Многие источники советуют программистам никогда не использоватьgetsв новых программах[1][2][3].Применение
getsвесьма осуждается. Функция оставлена в стандартах C89 и C99 для обратной совместимости. Множество инструментов разработки ПО, как например, GNU ld выдает предупреждения в случае обнаружения при компоновке кода с использованиемgets.Альтернативы
Вместо
getsмогут быть использованы другие функции строкового ввода, что позволит избежать ошибок, связанных с переполнением буфера. Простейшим вариантом будетfgets. При замене кода видаchar buffer[BUFFERSIZE]; gets(buffer);
кодом вида
char buffer[BUFFERSIZE]; fgets(buffer, sizeof(buffer), stdin);
нужно иметь в виду, что вызов
fgets(buffer, sizeof buffer, stdin)отличается отgets(buffer)не только защитой от переполнения буфера, но и тем, чтоfgets(buffer, sizeof buffer, stdin)сохраняет завершающий символ перевода строки (если ввод линии заканчивается символом перевода строки), в то время какgets(buffer)отбрасывает его.Безопасность использования
Безопасное использование
getsтребует от программиста проверки того, что переполнение буфера не станет проблемой. Стандарт языка Си этого не гарантирует; тем не менее, существует несколько относительно усложненных способов проверки этого с различной степенью переносимости. Одним из возможных вариантов является защитная страница для защиты памяти. Сам по себе этот метод переполнения буфера превращает в падения системы. В сочетании с обработчиками исключений, такими какSIGSEGVиsigaction, защитная страница может помочь с изящной обработкой ошибок.Примечания
- ↑ GNU GNU Библиотека Си — Строковый Ввод. — «Функция
getsвесьма опасна, так как она не обеспечивает никакой защиты от переполнения строкиs. Библиотека GNU включает ее только ради совместимости. Вам следует всегда использовать вместо нееfgetsилиgetline.» Архивировано из первоисточника 19 марта 2012. Проверено 2 августа 2008. - ↑ Почему все говорят не использовать
gets()?. comp.lang.c Часто Задаваемые Вопросы. Архивировано из первоисточника 19 марта 2012. Проверено 2 августа 2008. - ↑
gets(3)— страница справки man по библиотечным функциям GNU/Linux (англ.) — «Никогда не используйтеgets(). Так как невозможно сказать, не зная ничего о данных, сколько символов будет прочитаноgets(), и поэтомуgets()продолжит помещать символы в буфер и после его заполнения, что весьма опасно в использовании. Это способно нарушить информационную защиту компьютерной системы.»
Ссылки
gets— системные интерфейсы, The Single UNIX® Specification, выпуск 7 от The Open Group (англ.)
Категории:- Stdio.h
- Небезопасные функции Си
- ↑ GNU GNU Библиотека Си — Строковый Ввод. — «Функция
Wikimedia Foundation. 2010.