When I try to compile C code that uses the gets()
function with GCC, I get this warning:
(.text+0x34): warning: the `gets' function is dangerous and should not be used.
I remember this has something to do with stack protection and security, but I'm not sure exactly why.
How can I remove this warning and why is there such a warning about using gets()
?
If gets()
is so dangerous then why can't we remove it?
The C gets function is dangerous and has been a very costly mistake. Tony Hoare singles it out for specific mention in his talk "Null References: The Billion Dollar Mistake":
http://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare
The whole hour is worth watching but for his comments view from 30 minutes on with the specific gets criticism around 39 minutes.
Hopefully this whets your appetite for the whole talk, which draws attention to how we need more formal correctness proofs in languages and how language designers should be blamed for the mistakes in their languages, not the programmer. This seems to have been the whole dubious reason for designers of bad languages to push the blame to programmers in the guise of 'programmer freedom'.
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.Instead of using
gets
, you want to usefgets
, which has the signature(
fgets
, if it reads an entire line, will leave the'\n'
in the string; you'll have to deal with that.)It remained an official part of the language up to the 1999 ISO C standard, but it was officially removed by the 2011 standard. Most C implementations still support it, but at least gcc issues a warning for any code that uses it.
In C11(ISO/IEC 9899:201x),
gets()
has been removed. (It's deprecated in ISO/IEC 9899:1999/Cor.3:2007(E))In addition to
fgets()
, C11 introduces a new safe alternativegets_s()
:However, in the Recommended practice section,
fgets()
is still preferred.I would like to extend an earnest invitation to any C library maintainers out there who are still including
gets
in their libraries "just in case anyone is still depending on it": Please replace your implementation with the equivalent ofThis will help make sure nobody is still depending on it. Thank you.
You should not use
gets
since it has no way to stop a buffer overflow. If the user types in more data than can fit in your buffer, you will most likely end up with corruption or worse.In fact, ISO have actually taken the step of removing
gets
from the C standard (as of C11, though it was deprecated in C99) which, given how highly they rate backward compatibility, should be an indication of how bad that function was.The correct thing to do is to use the
fgets
function with thestdin
file handle since you can limit the characters read from the user.But this also has its problems such as:
To that end, almost every C coder at some point in their career will write a more useful wrapper around
fgets
as well. Here's mine:with some test code:
It provides the same protections as
fgets
in that it prevents buffer overflows but it also notifies the caller as to what happened and clears out the excess characters so that they do not affect your next input operation.Feel free to use it as you wish, I hereby release it under the "do what you damn well want to" licence :-)