Was gets ever useful? [closed]
Asked Answered
A

4

7

It seems to me, people, especially when learning the C programming language, are still using the gets function to read in data from stdin. Despite that it has now been removed1 from the C11 standard, and a disclaimer on cppreference reads:

The gets() function does not perform bounds checking, therefore this function is extremely vulnerable to buffer-overflow attacks. It cannot be used safely (unless the program runs in an environment which restricts what can appear on stdin). For this reason, the function has been deprecated in the third corrigendum to the C99 standard and removed altogether in the C11 standard. fgets() and gets_s() are the recommended replacements.

Never use gets().

However, it seems to be that this is not a new issue that came up with more modern programming philosophies. It would have always been broken and have caused programs to crash and I don't see what could possibly be meant by an "environment which restricts what can appear on stdin".

So, was it ever useful in the past? Or what is the reason it was added to previous standards and pre-standard versions of C?


(1) ... or at least changed to have an additional parameter indicating the maximal length to read. I am however asking about the old signature, receiving only a pointer.

Annulet answered 5/3, 2013 at 13:54 Comment(9)
From the FAQ "You should only ask practical, answerable questions based on actual problems that you face..." (my emphasis).Horsewhip
???? https://mcmap.net/q/162439/-c-scanf-vs-gets-vs-fgetsTrinhtrini
@T.J.Crowder - it also says "problems that are unique to the programming profession", you wouldn't ask about API usage outside of the programming professionRegret
@Mike: Yes, but I'm applying && to those criteria. You seem to be applying ||. :-) There's no "actual problem" here. I didn't make the rules of SO (and it would be a different place if I had), I'm just pointing them out.Horsewhip
@T.J.Crowder The inflammatory persistence of gets amongst beginners is an actual problem that we all face, so I don't see your point nor your VTC.Annulet
@bitmask: A further question on SO about it isn't going to change that. And with that point, I'm off to get on with some real work. :-) (Not some kind of lame dig, I have a conf call I need to get to... So maybe not real work...)Horsewhip
"environment which restricts what can appear on stdin" means , the guy using the terminal is aware , that he can't enter more than , what he thinks/guesses is the character array size , used in the program...Massingill
It might be a better question if phrased: "What is gets practical for?" Currently it's not possible to answer without defining "useful" and is likely to solicit debate, arguments or extended discussion. If you want the question re-opened, it needs to be factually answerable.Flyweight
@Tragedian: Thank you for your feedback (I do appreciate if people provide constructive commentary regarding close reasons). But what does your distinction of "useful" versus "practical" entail?Annulet
E
5

Yes, it was useful and "extremely vulnerable to buffer-overflow attacks" at the same time.

It would have always been broken and have caused programs to crash and I don't see what could possibly be meant by an "environment which restricts what can appear on stdin".

No, gets didn't cause programs to crash. It is primarily a security problem. You can read about buffer overflow attacks here

Also see this question: Why is the gets function so dangerous that it should not be used?

Explode answered 5/3, 2013 at 14:11 Comment(7)
As implicitly stated in the OP, these are contradictions. If I expose my program to buffer overruns by calling gets then it is distinctively not useful. The question asks if there used to be additional safeguards or if not, why gets was defined as it was.Annulet
@Annulet To me "useful" means that it can help achieve some useful functionality for the user. A program can be useful and unsafe at the same time...Explode
C was designed in the 70s. Back then, networked systems were the exception than the norm, and security wasn't considered as important as today. Data was generally considered to be as trustworthy as the software.Pennate
I'm sure gets will cause programs to crash with a much higher probability than causing security issues (which have to be carefully manufactured).Threadgill
I'm not even talking about security (as Aki observes). Especially for a systems programming language, crashes are disastrous and are completely orthogonal to security.Annulet
@Annulet Well, maybe you are not thinking about security, but the citation provided by you is clearly talking about buffer-overflow attacksExplode
+1 for the first sentence, although frankly that statement could be applied to all of C. :-)Ionium
P
5

When you look at remnants from the early days of C, you have to consider the historical background.

The C language was designed in the 70s. Back then, networked systems were the exception than the norm, and security wasn't considered as important as today. Systems were rarely operating on untrusted 3rd party data. And even when they were doing so, it wasn't considered that big of a risk. Information technology was still in its earliest stage. Nobody realized how sensitive computer systems could be.

CPU time, on the other hand, was precious. Programs needed to be as efficient as possible.

That's why most functions from the C standard library do no bound checking. Performance had a much higher priority than security. When you required security, you were supposed to validate your data before feeding it to your program.

But today in the 21st century, where all computer systems are interconnected, all computer systems are constantly processing information from untrusted or even unknown origins, and hacking is a billion dollar industry, security has become priority number one for every computer program.

Pennate answered 5/3, 2013 at 14:29 Comment(1)
I wasn't talking about security in today's sense but rather on robustness. But your speed argument is a very good one, which might have taken precedence over both security and robustness.Annulet
D
2

When gets was invented, very few programs needed to be able to accept large amounts of input from untrustworthy sources. gets is adequate for limited input from a co-operating user. This user provides "the environment which restricts what can appear", by not typing much on each line. You could pretty much count on a user sitting at a terminal not to type hundreds of bytes of data into a "y/n" prompt. If they piped a large file into your program, when your program wasn't designed for that, well, they got bad results.

Programs that did have to handle arbitrary input didn't use gets.

Now, malicious input is common in practice, and is more damaging since tools and techniques exist to allow attackers to easily turn buffer overflows to their advantage. A well-trained user typing at a prompt is a niche case. Furthermore, accounting for malicious input is widely used as a good technique in order to ensure that software is robust against unexpected input that wasn't intended as an attack. Pretty much all programs are expected to handle arbitrary input. So gets is clearly inadequate.

Deshabille answered 5/3, 2013 at 14:31 Comment(0)
T
0

Gets is still useful for prototyping. It is fast to write and produces expected results for the programmer, who is oriented in solving a problem at hand instead of trying to make his or her program to crash.

Threadgill answered 5/3, 2013 at 14:21 Comment(2)
fgets is as fast to write, really. Providing the buffer's size and the standard input FILE isn't that much of an obstacle.Annulet
@bitmask: The annoyance is having to use strlen to find the newline so it can be stripped out.Sulfur

© 2022 - 2024 — McMap. All rights reserved.