
Vinit Dhatrak
Cuando trato de compilar código C que usa el gets()
función con GCC, recibo esta advertencia:
(.text+0x34): advertencia: la función `gets’ es peligrosa y no debe usarse.
Recuerdo que esto tiene algo que ver con la protección y la seguridad de la pila, pero no estoy seguro exactamente por qué.
¿Cómo puedo eliminar esta advertencia y por qué existe tal advertencia sobre el uso gets()
?
Si gets()
es tan peligroso entonces ¿por qué no podemos eliminarlo?

Tomas Owens
Para usar gets
con seguridad, debe saber exactamente cuántos caracteres leerá, de modo que pueda hacer que su búfer sea lo suficientemente grande. Solo lo sabrá si sabe exactamente qué datos leerá.
En lugar de usar gets
quieres usar fgets
que tiene la firma
char* fgets(char *string, int length, FILE * stream);
(fgets
si lee una línea completa, dejará el '\n'
en la cadena; tendrás que lidiar con eso).
gets
siguió siendo una parte oficial del idioma hasta el estándar ISO C de 1999, pero se eliminó oficialmente en el 2011 estándar. La mayoría de las implementaciones de C aún lo admiten, pero al menos gcc emite una advertencia para cualquier código que lo use.
Porque gets
no realiza ningún tipo de comprobación al obtener bytes de Entrada estándar y ponerlos en algún lugar. Un ejemplo sencillo:
char array1[] = "12345";
char array2[] = "67890";
gets(array1);
Ahora, antes que nada, puede ingresar cuántos caracteres desea, gets
no le importará. En segundo lugar, los bytes sobre el tamaño de la matriz en la que los coloca (en este caso array1
) sobrescribirá todo lo que encuentre en la memoria porque gets
los escribirá. En el ejemplo anterior, esto significa que si ingresa "abcdefghijklmnopqrts"
tal vez, impredeciblemente, también se sobrescribirá array2
o lo que sea.
La función no es segura porque asume una entrada consistente. ¡NUNCA LO USE!

pmg
Leí recientemente, en un Publicación de USENET en comp.lang.c
ese gets()
se está eliminando del Estándar. WOOHOO
Te alegrará saber que el comité acaba de votar (por unanimidad, según parece) para eliminar gets() del borrador también.

yuhao
En C11 (ISO/CEI 9899:201x), gets()
ha sido removido. (Está en desuso en ISO/IEC 9899:1999/Cor.3:2007(E))
Además de fgets()
C11 presenta una nueva alternativa segura gets_s()
:
C11 K.3.5.4.1 El gets_s
función
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdio.h>
char *gets_s(char *s, rsize_t n);
Sin embargo, en el Práctica recomendada sección, fgets()
todavía se prefiere.
Él fgets
La función permite que los programas escritos correctamente procesen de forma segura las líneas de entrada demasiado largas para almacenarlas en la matriz de resultados. En general, esto requiere que los llamantes de fgets
preste atención a la presencia o ausencia de un carácter de nueva línea en la matriz de resultados. Considere usar fgets
(junto con cualquier procesamiento necesario basado en caracteres de nueva línea) en lugar de
gets_s
.
gets()
Ataque de desbordamiento de búfer– EsmaeelE
9 de diciembre de 2017 a las 12:41
más explicación_Bufferoverflow_C
gets()
– EsmaeelE
9 de diciembre de 2017 a las 12:42
Y tenga en cuenta que
scanf("%s", b)
tiene todos los mismos problemas quegets
.– William Pursell
16 de diciembre de 2020 a las 14:56