For many years, gets
has been universally disparaged as being an unsafe function. (The canonical SO question is Why is the gets function so dangerous that it should not be used?). The gets
function is so bad that it has been removed from the C11 language standard. Supporters of gets
(there are few if any) would argue that it is perfectly fine to use it if you know about the structure of the input.
Why do people who disparage gets
and acknowledge the folly of relying on the structure of the input allow the usage of %d
as a scanf
conversion specifier? That's a sociological question, and the real question is: why is %d
in a scanf
format string unsafe?
No, scanf("%d", …)
is not as bad as gets
.
gets
is as bad as it gets because it is not possible to use it safely, in virtually any environment. Buffer overflow is likely, cannot be prevented, and is quite likely to lead to arbitrarily bad consequences.
The worst thing that can happen with scanf("%d", …)
, on the other hand, is integer overflow. While this is theoretically also undefined behavior, in practice it virtually always results in either (a) quiet wraparound, (b) overflow to INT_MAX
or INT_MIN
, or (c) a runtime exception which may terminate the calling program.
It is extremely difficult to imagine a scenario under which an attacker could exploit a program using scanf("%d", …)
. Exploits involving gets
, on the other hand, are commonplace.
(Although not the question asked, it's true that scanf("%s", …)
is precisely as dangerous as gets
. It's a fair question why the former isn't always disparaged as strenuously as the latter.)