Как fopen_s может быть более безопасным, чем fopen?

Я работаю над устаревшим кодом для Windows Платформа. Когда я компилирую код в VS2013Дайте следующее предупреждение:

ошибка C4996: ‘fopen‘: Эта функция или переменная может быть небезопасной. Рассмотреть возможность использования fopen_s вместо. Чтобы отключить устаревание, используйте _CRT_SECURE_NO_WARNINGS. Смотрите справку для деталей.»

И это также даст знакомое предупреждение для sprintf, я понимаю sprintf_s более безопасен, чем sprintf из-за переполнения буфера.

Но как можно fopen_s быть более безопасным, чем fopen, нет никаких шансов переполнения буфера, потому что fopen не принимает буфер Может ли кто-нибудь представить случай fopen небезопасно, и fopen_s безопасно?

22

Решение

s в данном случае не означает «безопасный», он означает «повышенная безопасность». За fopen_sпараметры проверяются на достоверность перед попыткой открыть файл.

С fopen, вы можете передать NULL указатель на имя файла, и все, скорее всего, распадется на части. fopen_s не имеет этой проблемы (А).

Имейте в виду, что эти границы проверки интерфейсов, таких как fopen_s являются необязательный часть стандарта ИСО, подробно изложенная в Приложении K (во всяком случае, на C11). Реализации не требуется обеспечить их и, если честно, fopenи многие другие так называемые небезопасные функции совершенно безопасны, если вы знаете, что делаете как кодировщик.

Интересно отметить, что fopen_s будет ловить указатели NULL для вас, но не для недействительных указателей, поэтому его безопасность повышена, а не безопасна — вы все равно можете нанести некоторый ущерб, если передадите недействительный, но ненулевой указатель.

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


(А) От C11 K.3.5.2.1 The fopen_s function:

errno_t fopen_s (
FILE * restrict * restrict streamptr,
const char * restrict      filename,
const char * restrict      mode);

Время воспроизведения-ограничение

Ни один из streamptr, filename или mode не должен быть нулевым указателем.

Если есть нарушение ограничения времени выполнения, fopen_s не пытается открыть файл. Кроме того, если streamptr не является нулевым указателем, fopen_s устанавливает * streamptr в нулевой указатель.

Сравните это с C11 7.20.5.3 The fopen function в котором говорится, что имя файла и режим должны указывать на строку, но не указывают, что произойдет, если вы укажете NULL-указатель (большинство реализаций, скорее всего, завершится с ошибкой разыменования нулевого указателя).

23

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]