Warning: the gets function is Dangerous and should not be Used

Why gets function is dangerous and should not be used | In the Linux operating system if we are using gets function to take input for the string then we get a warning “implicit declaration of function ‘gets’; did you mean ‘fgets’? [-Wimplicit-function-declaration]” and another “warning: the `gets' function is dangerous and should not be used.” In C Language to read a string generally everyone use gets() function.

In order to use gets safely, you have to know exactly how many characters you will be reading so that you can make your buffer large enough. You will only know that if you know exactly what data you will be reading. The basic problem is that the function doesn’t know how big the buffer is, so it continues reading until it finds a newline or encounters EOF, and may overflow the bounds of the buffer it was given.

Consider that string str is a character array of size 10, i.e. str[10]. It can hold up to 10 characters. If the user inputs a string with length lesser than 10, it can be stored in str. What happens when the user inputs a string with length that is greater than 10, say 20? The 11th character shall go to str[10] (array indices start with 0, i.e. our original array is from s[0] to s[9]). Obviously this is outside the array, but C does no bound checking. So chances are, it may succeed, or in other words, overwrites the stack. It shall succeed until gets() reaches an address to which you have no access to. In Linux, its probably the dreaded Segmentation Fault, which can crash your system. It creates a big error in our program. There are a lot of viruses uses these methods to get into the software.

Also, scanf() have the same problem because it also doesn’t provide any facility to protect against buffer overflow. The scanf() function also read the stream of bits until an unknown type encountered, or encounter a space or a new line character.

#include<stdio.h>
int main()
{
   char str[10];
   printf("Enter string: ");
   gets(str);
   printf("String: %s",str);
   return 0;
}
Enter string: Know Program C Language
*** stack smashing detected ***:  terminated
Aborted (core dumped)
gets function is dangerous

The Morris worm or Internet worm of November 2, 1988, was one of the first computer worms distributed via the Internet, and the first to gain significant mainstream media attention. It used gets() and a buffer overflow as one of its methods of propagating from system to system. It also resulted in the first felony conviction in the US under the 1986 Computer Fraud and Abuse Act.

The C11 standard ISO/IEC 9899:2011 eliminated gets() as a standard function, which is A Good Thing (it was formally marked as ‘obsolescent’ and ‘deprecated’ in ISO/IEC 9899:1999/Cor.3:2007 — Technical Corrigendum 3 for C99, and then removed in C11). But it will remain in libraries for many years (meaning ‘decades’) for reasons of backward compatibility.

The solution of “gets function is dangerous”

The correct thing to do is to use the fgets function with the stdin file handle since you can limit the characters read from the user. fgets() has the signature:-

char* fgets(char *str, int length, FILE * stream);

The fgets() reads until a newline is encountered or until num-1 characters have been read, and puts a ‘\0’ at the end of the characters it reads into str. As long as you’ve allocated at least num characters for str, fgets() will work safely.

#include<stdio.h>
int main()
{
   char str[10];
   printf("Enter string: ");
   fgets(str, sizeof(str), stdin);
   printf("String: %s",str);
   return 0;
}

Output:-

Enter string: Know Program C Language
String: Know Prog

But this also has its problems such as:-

  • extra characters entered by the user will be picked up the next time around.
  • there’s no quick notification that the user entered too much data.
#include<stdio.h>
int main()
{
   char str1[10], str2[10];
   printf("Enter string: ");

   fgets(str1, sizeof(str1), stdin);
   fgets(str2, sizeof(str2), stdin);

   printf("String1: %s",str1);
   printf("String2: %s",str2);

   return 0;
}

Output:-

Enter string: Know Program C language
String1: Know ProgString2: ram C lan

If you enjoyed this post, share it with your friends. Do you want to share more information about the topic discussed above or do you find anything incorrect? Let us know in the comments. Thank you!

Similar C problems on Linux

Leave a Comment

Your email address will not be published. Required fields are marked *