0

I got a problem. I wanted to see the difference between the gets and scanf(). However, my terminal shows up as::

warning: this program uses gets(), which is unsafe. Abort trap: 6

Is there some rule where the gets() and scanfs() can't get together in one code??

#include <stdio.h>

int main(void){
    char passage[10];
    printf("Enter in a passage same one twice:: \n");
    scanf("%s", passage);
    gets(passage);

    printf("Using scanf:: %s", passage);
    printf("Using Gets:: %s", passage);
}

P.S. People say that I am currently writing on the memory that I don't own, but I don't get the problem in this code. Thanks!!!

  • 2
    You shouldn't use `gets()`, which has unavoidable risk of buffer overrun, deprecated in C99 and deleted in C11. – MikeCAT Jul 14 '16 at 05:35
  • 1
    `scanf("%s", passage);` leaves a `\n` for `gets(passage);` to read – chux - Reinstate Monica Jul 14 '16 at 05:35
  • 1
    [Couldn't reproduce](http://melpon.org/wandbox/permlink/nTeInlmoD6fPsw0F). Make sure that the input isn't too long to fit in the array (9 characters or less). – MikeCAT Jul 14 '16 at 05:37
  • 2
    `scanf()` with a `"%s"` format is as unsafe as `gets()`. – Keith Thompson Jul 14 '16 at 05:39
  • 1
    Where did you learn to use the `gets()` function? – dreamlax Jul 14 '16 at 05:43
  • 1
    See [Why the `gets()` function is too dangerous to be used](http://stackoverflow.com/questions/1694036/why-is-the-gets-function-dangerous-why-should-it-not-be-used) for details on why you should not use `gets()` ever. I would hazard a guess that your system has implemented `char *gets(char *s) { assert(s != 0); fprintf(stderr, "warning: this program uses gets(), which is not safe\n"); abort(); return 0; }` or thereabouts. Basically, there's a dummy version of `gets()` that crashes your program deliberately. Never, *never*, **never**, ***never***, ***NEVER*** use `gets()`. – Jonathan Leffler Jul 14 '16 at 05:44
  • 1
    Also, observe that `scanf()` leaves a newline in the input buffer, so the `gets()` will retrieve that as its 'line' of input. You should protect your `scanf()` too: it should us `if (scanf("%9s", passage) != 1) { …report error… }`. Also, since you read the values into the same variable, you're only going to see the same result twice. You need to use `passage1[10]` and `passage2[10]` or something — but 10 is ridiculously short and entirely error prone (use 4096 or something sensible like that instead; not less than 256, anyway). – Jonathan Leffler Jul 14 '16 at 05:48
  • What is your input ? – Jabberwocky Jul 14 '16 at 06:51

3 Answers3

2

gets() is vulnerable to buffer overflow and is therefore highly discouraged. This vulnerability comes from the fact that there is no way to specify how large the buffer you are passing to gets() actually is. In your case where passage is 10 chars long, imagine if the user typed 10 or more characters. The buffer would then start pointing to un-allocated memory and cause a stack-based buffer overflow.

It would seem the C library your compiler is using is attempting to prevent you from compiling vulnerable code. If you'd still like to use gets() please use fgets() instead and set the file pointer to stdin. The advantage of fgets() is it allows you to specify the buffer size. See more about fgets() here.

Update: also please take note of MikeCAT's comment to this post referencing the dangers of scanf("%s") as you've used it.

Brandon
  • 416
  • 2
  • 5
  • 6
    `scanf("%s", passage);` is also vulnerable to buffer overflow. Maximum input length should be specified like `scanf("%9s", passage);` – MikeCAT Jul 14 '16 at 05:41
1

It's not using gets and scanf together, it's using gets at ALL. The manpage for gets (http://man7.org/linux/man-pages/man3/gets.3.html) says it better than I could:

Never use gets(). Because it is impossible to tell without knowing the data in advance how many characters gets() will read, and because gets() will continue to store characters past the end of the buffer, it is extremely dangerous to use. It has been used to break computer security. Use fgets() instead. For more information, see CWE-242 (aka "Use of Inherently Dangerous Function") at http://cwe.mitre.org/data/definitions/242.html

qDot
  • 430
  • 3
  • 8
0

The basic difference [in reference to your particular scenario],

scanf() ends taking input upon encountering a whitespace, newline or EOF
gets() considers a whitespace as a part of the input string and ends the input upon encountering newline or EOF.


However, to avoid buffer overflow errors and to avoid security risks, its safer to use fgets().
Amar Srivastava
  • 373
  • 3
  • 10