0

How to get rid of buffer overflow on taking input from user? By using fgets or scanf? If fgets then how it prevents. Some explanation required as a beginner.

#include <stdio.h>
#include <stdlib.h>

int main(){
  char choice[5];
  char one='1', two='2', three='3';

  printf("%c. Create new account\n",one);
  printf("%c. Update information of existing account\n",two);
  printf("%c. For transactions\n",three);

  printf("Enter your choice: ");
  // fgets(choice, sizeof choice, stdin);      // This OR
  // fgets(choice, 3, stdin);                  // This one
  scanf("%s",choice);                          // This one
  printf("Here is your choice: %s", choice);

  return 0;
}
Bilal Khan
  • 27
  • 5
  • 1
    Does this answer your question? https://stackoverflow.com/questions/1621394/how-to-prevent-scanf-causing-a-buffer-overflow-in-c – DNT May 21 '20 at 23:24

1 Answers1

4

A well-written program reports invalid input with a comprehensible error message, not with a crash.

Fortunately, it is possible to avoid scanf buffer overflow by either specifying a field width or using the a flag.

When you specify a field width, you need to provide a buffer (using malloc or a similar function) of type char *.You need to make sure that the field width you specify does not exceed the number of bytes allocated to your buffer.

On the other hand, you do not need to allocate a buffer if you specify the a flag character -- scanf will do it for you. Simply pass scanf an pointer to an unallocated variable of type char *, and scanf will allocate however large a buffer the string requires, and return the result in your argument. This is a GNU-only extension to scanf functionality.

Here is a code example that shows first how to safely read a string of fixed maximum length by allocating a buffer and specifying a field width, then how to safely read a string of any length by using the a flag.

int main()
{
  int bytes_read;
  int nbytes = 100;
  char *string1, *string2;

  string1 = (char *) malloc (25);

  puts ("Please enter a string of 20 characters or fewer.");
  scanf ("%20s", string1);
  printf ("\nYou typed the following string:\n%s\n\n", string1);

  puts ("Now enter a string of any length.");
  scanf ("%as", &string2);
  printf ("\nYou typed the following string:\n%s\n", string2);

  return 0;
}

There are a couple of things to notice about this example program. First, notice that the second argument passed to the first scanf call is string1, not &string1. The scanf function requires pointers as the arguments corresponding to its conversions, but a string variable is already a pointer (of type char *), so you do not need the extra layer of indirection here. However, you do need it for the second call to scanf. We passed it an argument of &string2 rather than string2, because we are using the a flag, which allocates a string variable big enough to contain the characters it read, then returns a pointer to it.

Adam
  • 2,820
  • 1
  • 13
  • 33