fopen_s _crt_secure_no_warnings c++ windows msvcrt crt tr24731

c++ - _crt_secure_no_warnings - fopen fopen_s



¿Cómo pueden los fopen_s ser más seguros que los fopen? (1)

Estoy trabajando en el código heredado para la plataforma Windows . Cuando compilo el código en VS2013 , da la siguiente advertencia:

error C4996: '' fopen '': esta función o variable puede no ser segura. Considera usar fopen_s en fopen_s lugar. Para deshabilitar la desaprobación, utilice _CRT_SECURE_NO_WARNINGS. Consulte la ayuda en línea para obtener detalles."

Y también dará una advertencia familiar para el sprintf . Entiendo que sprintf_s es más seguro que sprintf debido al desbordamiento del búfer.

Pero, ¿cómo puede ser fopen_s más seguro que fopen No hay posibilidad de desbordamiento de búfer porque fopen no acepta un búfer. ¿Alguien puede proporcionar un caso que fopen no es seguro y que fopen_s es seguro?


La s no significa "seguro" en este caso, significa "seguridad mejorada". Para fopen_s , se comprueba la validez de los parámetros antes de intentar abrir el archivo.

Con fopen , puedes pasar un puntero NULO para el nombre del archivo y es probable que todo se caiga a pedazos. fopen_s no tiene ese problema (a) .

Tenga en cuenta que estas interfaces de verificación de límites como fopen_s son una parte opcional de la norma ISO, que se detalla en el Anexo K (como en C11, de todos modos). No es necesario que las implementaciones las proporcionen y, para ser honesto, fopen , y muchas otras funciones llamadas inseguras, son perfectamente seguras si sabes lo que estás haciendo como programador.

Es interesante observar que fopen_s atrapará los punteros NULL para usted pero no los punteros no válidos, por lo tanto, la seguridad mejorada en lugar de segura: aún puede causar algún daño si pasa un puntero no válido pero no NULL.

Otras funciones "seguras" que lo obligan a proporcionar tamaños de búfer de destino también son seguras siempre que pase el tamaño correcto. Pasa algo demasiado grande y todas las apuestas están apagadas.

(a) De 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);

Restricciones de tiempo de ejecución

Ninguno de streamptr, filename o mode será un puntero nulo.

Si hay una violación de restricción de tiempo de ejecución, fopen_s no intenta abrir un archivo. Además, si streamptr no es un puntero nulo, fopen_s establece * streamptr en el puntero nulo.

Contraste que con C11 7.20.5.3 The fopen function que indica que el nombre de archivo y el modo deben apuntar a una cadena pero no especificar qué sucede si proporciona un puntero NULO (la mayoría de las implementaciones probablemente se bloquearían con una desreferencia de puntero nulo).