By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,786 Members | 2,241 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,786 IT Pros & Developers. It's quick & easy.

Why is it dangerous?

P: n/a
'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows? Where can I download a
non dangerous gets function? I have never used gets before is
there undefined behavior somewhere?
Here is a trimmed down example program from my assignment that
demonstrates the problem

#include <stdio.h>
#include <malloc.h>

void main()
{
char *string;
printf("enter string (max 2000 chars): ");
fflush(stdin);
fflush(stdout);
string = (char *)malloc(2001);
if(!string) exit(1);
gets(string);
printf("you entered: %s\n", string);
free(string);
exit(0);
}

On windows with TurboC and Lcc no error is printed. On linux with
gcc it says gets is dangerous.

Please advise my instructor says gcc is overly pedantic.
Aug 10 '08 #1
Share this Question
Share on Google+
233 Replies


P: n/a
Julian said:
'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows?
No. Your Linux compiler warned you about a dangerous function that should
never be used. Your Windows compiler clearly forgot to do this. So it
could be argued that Windows is more dangerous than Linux.
Where can I download a
non dangerous gets function?
Nowhere. The functionality of gets() is defined by ISO; it takes a pointer
to the first character in a buffer, and stores an entire line from stdin
into that buffer, *regardless of the buffer's size*!! There is no safe way
to use such a function.

Instead, you can use fgets(), another standard ISO C function, which lets
you specify the size of the buffer, and which will not attempt to store
more in the buffer than you say will fit. So if you get the size right,
fgets() is not dangerous.
I have never used gets before is
there undefined behavior somewhere?
It depends on how well-behaved your user is (will they restrain themselves
and only type as many characters as you've provided for in your buffer?),
but it's safest to assume that you should never, ever, ever use gets().
Here is a trimmed down example program from my assignment that
demonstrates the problem

#include <stdio.h>
#include <malloc.h>
C has no header by that name (although some implementations do). For the
prototypes for malloc and free, #include <stdlib.hinstead.
>
void main()
int main(void)
{
char *string;
printf("enter string (max 2000 chars): ");
fflush(stdin);
The behaviour of fflush is defined only for streams open for output or
update, whereas stdin is open only for input. In short, Don't Do That.
fflush(stdout);
That's fine, and meaningful in this case, because your printf string didn't
end in a newline, so you need to flush data from the buffer to the output
device.
string = (char *)malloc(2001);
string = malloc(2001); will be perfectly adequate. You do not need the
cast, and in fact it's a bad idea.
if(!string) exit(1);
Better: exit(EXIT_FAILURE); This macro is defined in <stdlib.hand has
portable semantics.
gets(string);
No, use this instead:

if(fgets(string, 2001, stdin) != NULL)
{
printf("you entered: %s\n", string);
free(string);
}
exit(0);
}

On windows with TurboC and Lcc no error is printed. On linux with
gcc it says gets is dangerous.

Please advise my instructor says gcc is overly pedantic.
Your instructor is underly pedantic. (So is gcc, unless you kick it hard.)

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 10 '08 #2

P: n/a
Julian wrote:
>
Please advise my instructor says gcc is overly pedantic.
As Richard said, the opposite is true unless you invoke gcc with the
correct options. That's why it has a -pedantic option!

As a learner using gcc, you should use

gcc -ansi -Wall -pedantic

as a minimum set of options. Substitute '-std=c99' for '-ansi' if you
are learning C99.

--
Ian Collins.
Aug 10 '08 #3

P: n/a
On Aug 9, 7:42*pm, Julian <ju**@nospam.invalidwrote:
'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows? Where can I download a
non dangerous gets function? I have never used gets before is
there undefined behavior somewhere?

Here is a trimmed down example program from my assignment that
demonstrates the problem

#include <stdio.h>
#include <malloc.h>

void main()
{
* * char *string;
* * printf("enter string (max 2000 chars): ");
* * fflush(stdin);
* * fflush(stdout);
* * string = (char *)malloc(2001);
* * if(!string) exit(1);
* * gets(string);
* * printf("you entered: %s\n", string);
* * free(string);
* * exit(0);

}

On windows with TurboC and Lcc no error is printed. On linux with
gcc it says gets is dangerous.

Please advise my instructor says gcc is overly pedantic.
(Leaving aside all the errors in the code that other people have
already pointed out and will continue to point out...)

It has nothing to do with the operating system, it has nothing to do
with the compiler, it has nothing to do with your instructor; it has
to do with gets(), and gets() alone (and you can't get a "safer"
gets(), BTW). The problem is that gets() has no way to know the size
of the buffer you pass to it, and it will continue to read until a
newline. You allocated 2001 bytes, which is reasonably large enough
for a line of text. But... suppose a cracker gets to your program and
gives you this line on the terminal:

enter string (max 2000 chars):
11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 11111111111111111111111111111111111111111111111111 1

Those are 2001 characters. There you go, the cracker overflowed your
buffer.

Sebastian

Aug 10 '08 #4

P: n/a
>When I compile a program from our C course with a windows compiler
>there is no problem but when I try to compile it with a linux compiler
it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.
As others have stated, there is no way to tell gets() how big the
buffer is, and no way to prevent someone from overflowing it.

Given the auto-repeat rate on your keyboard, how long does it take
a cat sleeping on the keyboard (and pressing down a key) to exceed
2000 characters?
>Is linux more dangerous than windows?
Linux seems to be giving better warnings than windows.
>Where can I download a
non dangerous gets function?
There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().
>I have never used gets before is
there undefined behavior somewhere?
There is no way to prevent buffer overflow by a careless or
malicious user.

Aug 10 '08 #5

P: n/a
Julian <ju**@nospam.invalidwrites:
[...]
#include <stdio.h>
#include <malloc.h>

void main()
{
char *string;
printf("enter string (max 2000 chars): ");
fflush(stdin);
fflush(stdout);
string = (char *)malloc(2001);
if(!string) exit(1);
gets(string);
printf("you entered: %s\n", string);
free(string);
exit(0);
}
[...]

This program, in 16 lines, exhibits at least 6 blatant errors or
gratuitous non-portabilities that have been discussed repeatedly in
this newsgroup: <malloc.h>, "void main()", "fflush(stdin), casting the
result of malloc(), exit(1), and of course the use of gets().

Either this is deliberate, and Julian is a troll, or it's not, and
he's been very poorly taught. In the latter case, Julian, please read
read the comp.lang.c FAQ <http://www.c-faq.com/>, and feel free to
post again if you still have any questions.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 10 '08 #6

P: n/a
Ian Collins wrote:
Julian wrote:
>Please advise my instructor says gcc is overly pedantic.

As Richard said, the opposite is true unless you invoke gcc with
the correct options. That's why it has a -pedantic option!

As a learner using gcc, you should use

gcc -ansi -Wall -pedantic

as a minimum set of options. Substitute '-std=c99' for '-ansi'
if you are learning C99.
Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 10 '08 #7

P: n/a
CBFalconer wrote:
Ian Collins wrote:
>Julian wrote:
>>Please advise my instructor says gcc is overly pedantic.

As Richard said, the opposite is true unless you invoke gcc with
the correct options. That's why it has a -pedantic option!

As a learner using gcc, you should use

gcc -ansi -Wall -pedantic

as a minimum set of options. Substitute '-std=c99' for '-ansi'
if you are learning C99.

Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.
I would also recommend:

-Wfloat-equal
-Wshadow
-Wpointer-arith
-Wbad-function-cast
-Wcast-qual
-Wcast-align
-Wwrite-strings
-Wstrict-prototypes
-Wold-style-definition
-Wmissing-prototypes
-Wredundant-decls
-Wunreachable-code

Aug 10 '08 #8

P: n/a
On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
CBFalconer wrote:
>Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.

I would also recommend:
[...]
-Wwrite-strings
I would not, since it deliberately makes the compiler nonconforming. For
those that understand in what ways, it can be useful, but they can find
the option themselves. CBFalconer included that option in his
recommendations recently, and I'm glad he dropped it.
Aug 10 '08 #9

P: n/a
Harald van D?k wrote:
On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
>CBFalconer wrote:
>>Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.

I would also recommend:
[...]
-Wwrite-strings

I would not, since it deliberately makes the compiler nonconforming.
For those that understand in what ways, it can be useful, but they can
find the option themselves. CBFalconer included that option in his
recommendations recently, and I'm glad he dropped it.
Thanks for that. I do remember that subthread now, but I passed over it,
being pressed for time. Now, to the Google Groups archive...

Aug 10 '08 #10

P: n/a

"Gordon Burditt" <go***********@burditt.orgwrote in message
There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().
This is a hardy annual.
Of course fgets() can be used safely, but won't be. For instance Richard
Heathfield posted a dangerous use of fgets() in this very thread. It will
give the wrong answer if the user enters a string of over 2000 characters.
Of course it is not dangerous in a little exercise program that doesn't do
anything, but then neither is gets().

To use fgets() safely you must check for the newline. If it is not present a
buffer overflow occurred. So you must then take action against the buffer to
ensure that the next read doesn't get the remainder of the previous line.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 10 '08 #11

P: n/a
Harald van Dijk wrote:
On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
>CBFalconer wrote:
>>Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.
I would also recommend:
[...]
-Wwrite-strings

I would not, since it deliberately makes the compiler nonconforming. For
those that understand in what ways, it can be useful, but they can find
the option themselves. CBFalconer included that option in his
recommendations recently, and I'm glad he dropped it.
Even so, it would save a lot of noise here if it where the default in gcc!

--
Ian Collins.
Aug 10 '08 #12

P: n/a
"Malcolm McLean" <re*******@btinternet.comwrites:
"Gordon Burditt" <go***********@burditt.orgwrote in message
>There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().
This is a hardy annual.
Of course fgets() can be used safely, but won't be. For instance
Richard Heathfield posted a dangerous use of fgets() in this very
thread. It will give the wrong answer if the user enters a string of
over 2000 characters.
You have allowed yourself to slip into polemic. It is not clear, at
least to me, what the right answer is so you are stretching the point
-- be careful with fgets and long lines -- by saying that the answer
is "wrong" and the use "dangerous".

--
Ben.
Aug 10 '08 #13

P: n/a
On 10 Aug 2008 at 0:59, Richard Heathfield wrote:
Julian said:
>a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

The functionality of gets() is defined by ISO; it takes a pointer to
the first character in a buffer, and stores an entire line from stdin
into that buffer, *regardless of the buffer's size*!! There is no safe
way to use such a function.
Of course, this is nonsense. There is a perfectly safe way to use
gets(), namely by being in control of what appears on stdin. Here in the
real world, people write all sorts of scraps of in-house code to run
once and forget about. They use fscanf() without elaborate error
checking, because they are 100% sure of the format of the input files.
gets() is no different.

Of course, in any production code, or any code at all where someone
other than the programmers will be able to decide what appears on stdin,
then gets() should not be used, the return value of p=malloc(10) should
be checked, etc. etc.

Instead of gets(), use whatever safe function is available on your
platform. For example, on GNU systems there is a getline() function
provided by stdio.h, which will dynamically allocated a big enough
buffer using malloc(). Or, roll your own getline function if portability
is a big issue for you.

Aug 10 '08 #14

P: n/a
Richard Heathfield <rj*@see.sig.invalidwrites:
Julian said:
>'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows?

No. Your Linux compiler warned you about a dangerous function that should
never be used.
Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the program/process/function
has a totally controlled and defined input stream. In those scenarios
gets is used flawlessly in millions of programs around the world.

if you can NOT define the input then I would agree. But in the real
world the input is indeed guarenteed in a properly functioning
system. if the system isn't well defined then all "bets are off" since
you can pretty much be sure that undefined behaviour/input has already
compromised the process pipeline.
Aug 10 '08 #15

P: n/a
santosh wrote:
CBFalconer wrote:
>Ian Collins wrote:
>>Julian wrote:

Please advise my instructor says gcc is overly pedantic.

As Richard said, the opposite is true unless you invoke gcc with
the correct options. That's why it has a -pedantic option!

As a learner using gcc, you should use

gcc -ansi -Wall -pedantic

as a minimum set of options. Substitute '-std=c99' for '-ansi'
if you are learning C99.

Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.

I would also recommend:

-Wfloat-equal
-Wshadow
-Wpointer-arith
-Wbad-function-cast
-Wcast-qual
-Wcast-align
-Wwrite-strings
-Wstrict-prototypes
-Wold-style-definition
-Wmissing-prototypes
-Wredundant-decls
-Wunreachable-code
I wouldn't, although those may be useful. The OP is obviously a
newbie, and is not going to remember all that. It is only useful
when implemented via an alias, a script, or a makefile, etc. What
I recommended is a minimum to ensure reasonably correct standard C
code.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 10 '08 #16

P: n/a
Malcolm McLean wrote:
"Gordon Burditt" <go***********@burditt.orgwrote:
>There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().

This is a hardy annual. Of course fgets() can be used safely, but
won't be. For instance Richard Heathfield posted a dangerous use of
fgets() in this very thread. It will give the wrong answer if the
user enters a string of over 2000 characters. Of course it is not
dangerous in a little exercise program that doesn't do anything,
but then neither is gets().

To use fgets() safely you must check for the newline. If it is not
present a buffer overflow occurred. So you must then take action
against the buffer to ensure that the next read doesn't get the
remainder of the previous line.
Or just get the remainder of the line. No overflow has occurred.

And you can avoid all those problems by using the (released to
public domain) ggets() function, available in standard C source
form at:

<http://cbfalconer.home.att.net/downlod/ggets.zip>

ggets gets complete lines, is safe, and has the simplicity of
gets. Malicious users can run the system out of assignable heap
memory, but will normally have to work hard to do so.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 10 '08 #17

P: n/a
santosh wrote:
Harald van D?k wrote:
>santosh wrote:
>>CBFalconer wrote:

Correction: That omits many useful tests. I suggest:

gcc -W -Wall -ansi -pedantic

for better error detection.

I would also recommend:
[...]
-Wwrite-strings

I would not, since it deliberately makes the compiler nonconforming.
For those that understand in what ways, it can be useful, but they
can find the option themselves. CBFalconer included that option in
his recommendations recently, and I'm glad he dropped it.

Thanks for that. I do remember that subthread now, but I passed over
it, being pressed for time. Now, to the Google Groups archive...
I didn't drop it. I conceded your 'non-standard' point. I
maintain that, for new code, including it will result in better
code, and maintain conformity. It may object to some actually
conforming code.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 10 '08 #18

P: n/a
Richard wrote:
Richard Heathfield <rj*@see.sig.invalidwrites:
>Julian said:
>>'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux
compiler it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows?

No. Your Linux compiler warned you about a dangerous function that
should never be used.

Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the
program/process/function has a totally controlled and defined input
stream. In those scenarios gets is used flawlessly in millions of
programs around the world.

if you can NOT define the input then I would agree. But in the real
world the input is indeed guarenteed in a properly functioning
system. if the system isn't well defined then all "bets are off" since
you can pretty much be sure that undefined behaviour/input has already
compromised the process pipeline.
I wonder, can you give examples of sources of perfectly controlled and
defined input? Certainly disk files can be tampered, as can pipes,
sockets and almost every other device. Why risk it with gets when fgets
is just as easy and safer?

Aug 10 '08 #19

P: n/a
On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
CBFalconer wrote:
>Correction: That omits many useful tests. I suggest:
gcc -W -Wall -ansi -pedantic
for better error detection.

I would also recommend:
[...]
-Wpointer-arith
This is redundant, since it's already enabled by -pedantic.

Aug 10 '08 #20

P: n/a
On 10 Aug 2008 at 13:17, santosh wrote:
Richard wrote:
>Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the
program/process/function has a totally controlled and defined input
stream. In those scenarios gets is used flawlessly in millions of
programs around the world.

I wonder, can you give examples of sources of perfectly controlled and
defined input? Certainly disk files can be tampered, as can pipes,
sockets and almost every other device.
True. The world might also be destroyed in a nuclear holocaust while
your throwaway program is reading its non-life-critical data, so why
take the risk of programming at all? Drink a beer, get laid, and wait
for the mushroom cloud to take you.

Aug 10 '08 #21

P: n/a
santosh <sa*********@gmail.comwrites:
Richard wrote:
>Richard Heathfield <rj*@see.sig.invalidwrites:
>>Julian said:

'evening.

I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.

When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux
compiler it complains that

a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.

Is linux more dangerous than windows?

No. Your Linux compiler warned you about a dangerous function that
should never be used.

Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the
program/process/function has a totally controlled and defined input
stream. In those scenarios gets is used flawlessly in millions of
programs around the world.

if you can NOT define the input then I would agree. But in the real
world the input is indeed guarenteed in a properly functioning
system. if the system isn't well defined then all "bets are off" since
you can pretty much be sure that undefined behaviour/input has already
compromised the process pipeline.

I wonder, can you give examples of sources of perfectly controlled and
defined input? Certainly disk files can be tampered, as can pipes,
sockets and almost every other device. Why risk it with gets when fgets
is just as easy and safer?
If I have a well defined pipeline then any deviance make the entire line
corrupt.

If I have a process whose DEFINED input is say, 16 characters at a time
on its standard input then its not its job to ensure thats what
comes. Dont believe me? Try calling strcpy with NULL pointer as the
destination.

Since it has NO way of reporting back errors to the program feeding it,
what should me module do? Carry on processing this rogue data?

The point is this - one can worry all day long. Once can also be
practical and "real".

Its like the malloc business. If malloc fails for a few bytes the chance
of that program not exhibiting "Undefined Bahvaiour" because you checked
the return code is practically nil.

Aug 10 '08 #22

P: n/a
On Aug 10, 12:42*pm, Richard<rgr...@gmail.comwrote:
Richard Heathfield <r...@see.sig.invalidwrites:
Julian said:
I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.
When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that
a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.
Is linux more dangerous than windows?
No. Your Linux compiler warned you about a dangerous function that should
never be used.

Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the program/process/function
has a totally controlled and defined input stream. In those scenarios
gets is used flawlessly in millions of programs around the world.

if you can NOT define the input then I would agree. But in the real
world the input is indeed guarenteed in a properly functioning
system.
hardly. Much web based software does not have total control
of its inputs. Compilers don't have TCOI. Even if the other end of
your
"link" is "trusted" there can be errors made. Yes, you test your
software but
why not on the length of input
if the system isn't well defined then all "bets are off" since
you can pretty much be sure that undefined behaviour/input has already
compromised the process pipeline
how many bugs has gets() caused? Windows certainly. Wasn't the Unix
worm gets() based?
--
Nick Keighley
Aug 10 '08 #23

P: n/a

"Antoninus Twink" <no****@nospam.invalidschreef in bericht
news:sl*******************@nospam.invalid...
True. The world might also be destroyed in a nuclear holocaust while
your throwaway program is reading its non-life-critical data, so why
take the risk of programming at all? Drink a beer, get laid, and wait
for the mushroom cloud to take you.
I agree except on one thing. I'd drink the beer last
>
Aug 10 '08 #24

P: n/a
Nick Keighley <ni******************@hotmail.comwrites:
On Aug 10, 12:42*pm, Richard<rgr...@gmail.comwrote:
>Richard Heathfield <r...@see.sig.invalidwrites:
Julian said:
>I'm not new to C and have been programming in it since I was 8 but
here's a strange problem I've never seen before.
>When I compile a program from our C course with a windows compiler
there is no problem but when I try to compile it with a linux compiler
it complains that
>a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should not be used.
>Is linux more dangerous than windows?
No. Your Linux compiler warned you about a dangerous function that should
never be used.

Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the program/process/function
has a totally controlled and defined input stream. In those scenarios
gets is used flawlessly in millions of programs around the world.

if you can NOT define the input then I would agree. But in the real
world the input is indeed guarenteed in a properly functioning
system.

hardly. Much web based software does not have total control
of its inputs. Compilers don't have TCOI. Even if the other end of
The dont use gets in this case.

You seem to think I am advocating it when the input is not DEFINED. I am
not.
Aug 10 '08 #25

P: n/a
"Serve Lau" <ni***@qinqin.comwrites:
"Antoninus Twink" <no****@nospam.invalidschreef in bericht
news:sl*******************@nospam.invalid...
>True. The world might also be destroyed in a nuclear holocaust while
your throwaway program is reading its non-life-critical data, so why
take the risk of programming at all? Drink a beer, get laid, and wait
for the mushroom cloud to take you.

I agree except on one thing. I'd drink the beer last
You would? I would drink it second.
Aug 10 '08 #26

P: n/a

"Ben Bacarisse" <be********@bsb.me.ukwrote in message news:
"Malcolm McLean" <re*******@btinternet.comwrites:
>"Gordon Burditt" <go***********@burditt.orgwrote in message
>>There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().
This is a hardy annual.
Of course fgets() can be used safely, but won't be. For instance
Richard Heathfield posted a dangerous use of fgets() in this very
thread. It will give the wrong answer if the user enters a string of
over 2000 characters.

You have allowed yourself to slip into polemic. It is not clear, at
least to me, what the right answer is so you are stretching the point
-- be careful with fgets and long lines -- by saying that the answer
is "wrong" and the use "dangerous".
if I enter

"My name is Rumplewumple ... stiltskin"
and the program comes back

"You entered My name is Rumplewumple ... stilt"

Then I might well object that that's my cousin. Which is potentially
dangerous, depending on what the program is being used for.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Aug 10 '08 #27

P: n/a
On Sun, 10 Aug 2008 09:27:13 +0100, "Malcolm McLean"
<re*******@btinternet.comwrote:
>
"Gordon Burditt" <go***********@burditt.orgwrote in message
>There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().
This is a hardy annual.
Of course fgets() can be used safely, but won't be. For instance Richard
Heathfield posted a dangerous use of fgets() in this very thread. It will
give the wrong answer if the user enters a string of over 2000 characters.
Any code that does not check the status of "service requests" is
dangerous. But this is a result of sloppy programming. It is not an
inherent property of the request itself as a call to gets() is.
>Of course it is not dangerous in a little exercise program that doesn't do
anything, but then neither is gets().
I guess on your system undefined behavior can never do any harm.
>
To use fgets() safely you must check for the newline. If it is not present a
buffer overflow occurred. So you must then take action against the buffer to
Actually, a buffer overflow was prevented.
>ensure that the next read doesn't get the remainder of the previous line.
The recommended action should be either:

Whatever the program needs to do to obtain the remainder of
the line so the input can be processed as intended .

Reject the input with appropriate notification to the user and
suitable follow-on action

--
Remove del for email
Aug 10 '08 #28

P: n/a
Antoninus Twink wrote:
On Sun, 10 Aug 2008 13:27:34 +0530, santosh wrote:
>CBFalconer wrote:
>>Correction: That omits many useful tests. I suggest:
gcc -W -Wall -ansi -pedantic
for better error detection.

I would also recommend:
[...]
-Wpointer-arith

This is redundant, since it's already enabled by -pedantic.
This is not mentioned in my gcc documentation. Looking it up on the
Web... yes I see you're right. Must have been added recently.

Aug 10 '08 #29

P: n/a
Malcolm McLean wrote:
>
"Ben Bacarisse" <be********@bsb.me.ukwrote in message news:
>"Malcolm McLean" <re*******@btinternet.comwrites:
>>"Gordon Burditt" <go***********@burditt.orgwrote in message
There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().

This is a hardy annual.
Of course fgets() can be used safely, but won't be. For instance
Richard Heathfield posted a dangerous use of fgets() in this very
thread. It will give the wrong answer if the user enters a string of
over 2000 characters.

You have allowed yourself to slip into polemic. It is not clear, at
least to me, what the right answer is so you are stretching the point
-- be careful with fgets and long lines -- by saying that the answer
is "wrong" and the use "dangerous".
if I enter

"My name is Rumplewumple ... stiltskin"
and the program comes back

"You entered My name is Rumplewumple ... stilt"

Then I might well object that that's my cousin. Which is potentially
dangerous, depending on what the program is being used for.
If the integrity of your data is valuable, you have to program
carefully. Simple isn't it. In such situations using fgets()
simplistically is not good enough, but it's still *better* than gets.
It's a question of getting data a little wrong or overrunning buffers
with *any* consequences from an immediate crash (lucky you) to altering
valuable data elsewhere.

There is no debate whether gets or fgets is safer. The latter is
*always* the safer option. If you want a line getting function with the
interface of gets, then it's easy enough to write your own.

Aug 10 '08 #30

P: n/a
Antoninus Twink wrote:
On 10 Aug 2008 at 13:17, santosh wrote:
>Richard wrote:
>>Total and utter nonsense. C is used all over the place for creating
elements which are under strict control and the
program/process/function has a totally controlled and defined input
stream. In those scenarios gets is used flawlessly in millions of
programs around the world.

I wonder, can you give examples of sources of perfectly controlled
and defined input? Certainly disk files can be tampered, as can
pipes, sockets and almost every other device.

True. The world might also be destroyed in a nuclear holocaust while
your throwaway program is reading its non-life-critical data, so why
take the risk of programming at all? Drink a beer, get laid, and wait
for the mushroom cloud to take you.
I'd use fgets even for a "throwaway" program because it's really as easy
to use and I won't have to worry about carefully deleting the sources
later.

Aug 10 '08 #31

P: n/a
CBFalconer <cb********@yahoo.comwrites:
santosh wrote:
>Harald van D?k wrote:
>>santosh wrote:
CBFalconer wrote:

Correction: That omits many useful tests. I suggest:
>
gcc -W -Wall -ansi -pedantic
>
for better error detection.

I would also recommend:
[...]
-Wwrite-strings

I would not, since it deliberately makes the compiler nonconforming.
For those that understand in what ways, it can be useful, but they
can find the option themselves. CBFalconer included that option in
his recommendations recently, and I'm glad he dropped it.

Thanks for that. I do remember that subthread now, but I passed over
it, being pressed for time. Now, to the Google Groups archive...

I didn't drop it. I conceded your 'non-standard' point. I
maintain that, for new code, including it will result in better
code, and maintain conformity. It may object to some actually
conforming code.
So it seems you did not accept *my* point of a program that requires a
diagnostic which -Wwrite-strings suppresses.

--
Ben.
Aug 10 '08 #32

P: n/a
Malcolm McLean wrote:
"Ben Bacarisse" <be********@bsb.me.ukwrote in message news:
.... snip ...
>>
You have allowed yourself to slip into polemic. It is not clear,
at least to me, what the right answer is so you are stretching
the point -- be careful with fgets and long lines -- by saying
that the answer is "wrong" and the use "dangerous".

if I enter
"My name is Rumplewumple ... stiltskin"
and the program comes back
"You entered My name is Rumplewumple ... stilt"

Then I might well object that that's my cousin. Which is potentially
dangerous, depending on what the program is being used for.
If that happens you have made an error in writing the program. It
is simple to avoid any such result while using fgets.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 10 '08 #33

P: n/a
In article <3a********************************@4ax.com>, Barry Schwarz <sc******@dqel.comwrote:
>On Sun, 10 Aug 2008 09:27:13 +0100, "Malcolm McLean"
<re*******@btinternet.comwrote:
>>
"Gordon Burditt" <go***********@burditt.orgwrote in message
>>There is no non-dangerous gets() function with the same interface.
The non-dangerous function is called fgets().
This is a hardy annual.
Of course fgets() can be used safely, but won't be. For instance Richard
Heathfield posted a dangerous use of fgets() in this very thread. It will
give the wrong answer if the user enters a string of over 2000 characters.

Any code that does not check the status of "service requests" is
dangerous. But this is a result of sloppy programming. It is not an
inherent property of the request itself as a call to gets() is.
Since gets() returns the same indication both when the input overflows the
buffer allocated for it, and when it doesn't -- thus necessarily precluding
the possibility of any such status check -- it could be argued that the use of
gets() constitutes "sloppy programming" in and of itself.
>
>>Of course it is not dangerous in a little exercise program that doesn't do
anything, but then neither is gets().

I guess on your system undefined behavior can never do any harm.
>>
To use fgets() safely you must check for the newline. If it is not present a
buffer overflow occurred. So you must then take action against the buffer to

Actually, a buffer overflow was prevented.
>>ensure that the next read doesn't get the remainder of the previous line.

The recommended action should be either:

Whatever the program needs to do to obtain the remainder of
the line so the input can be processed as intended .

Reject the input with appropriate notification to the user and
suitable follow-on action
Exactly so.
Aug 10 '08 #34

P: n/a
Ben Bacarisse wrote:
CBFalconer <cb********@yahoo.comwrites:
.... snip ...
>
>I didn't drop it. I conceded your 'non-standard' point. I
maintain that, for new code, including it will result in better
code, and maintain conformity. It may object to some actually
conforming code.

So it seems you did not accept *my* point of a program that
requires a diagnostic which -Wwrite-strings suppresses.
No. I consider the chance of a complex program trying to write to
a non-writable string is more likely than the case you brought up
(which I have absent-mindedly forgotten). And, if I need it, I am
quite capable of remove -Wwrite-strings from the command for a
particular compilation.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.

Aug 11 '08 #35

P: n/a
CBFalconer <cb********@yahoo.comwrites:
Ben Bacarisse wrote:
>CBFalconer <cb********@yahoo.comwrites:
... snip ...
>>
>>I didn't drop it. I conceded your 'non-standard' point. I
maintain that, for new code, including it will result in better
code, and maintain conformity. It may object to some actually
conforming code.

So it seems you did not accept *my* point of a program that
requires a diagnostic which -Wwrite-strings suppresses.

No. I consider the chance of a complex program trying to write to
a non-writable string is more likely than the case you brought up
(which I have absent-mindedly forgotten). And, if I need it, I am
quite capable of remove -Wwrite-strings from the command for a
particular compilation.
I think we have crossed wires. I use that option. I think it useful
and I know you can remove it when you need to (as I can). It is just
that you seemed to be suggesting that it did not break conformity,
only that it objected to some conforming code. People (particularly
learners) should know that it silently allows some programs though
that should have a constraint diagnosed.

--
Ben.
Aug 11 '08 #36

P: n/a
santosh wrote:
Antoninus Twink wrote:
>santosh wrote:
>>CBFalconer wrote:

Correction: That omits many useful tests. I suggest:
gcc -W -Wall -ansi -pedantic
for better error detection.

I would also recommend:
[...]
-Wpointer-arith

This is redundant, since it's already enabled by -pedantic.

This is not mentioned in my gcc documentation. Looking it up on the
Web... yes I see you're right. Must have been added recently.
I am running gcc 3.2.1, dated 2002, and that option is available.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
Aug 11 '08 #37

P: n/a
CBFalconer <cb********@yahoo.comwrites:
santosh wrote:
>Antoninus Twink wrote:
>>santosh wrote:
CBFalconer wrote:

Correction: That omits many useful tests. I suggest:
gcc -W -Wall -ansi -pedantic
for better error detection.

I would also recommend:
[...]
-Wpointer-arith

This is redundant, since it's already enabled by -pedantic.

This is not mentioned in my gcc documentation. Looking it up on the
Web... yes I see you're right. Must have been added recently.

I am running gcc 3.2.1, dated 2002, and that option is available.
The question wasn't whether it's available, it was whether
"-Wpointer-arith" is enabled by "-pedantic".

In any case, it would be a good question for gnu.gcc.help.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Aug 11 '08 #38

P: n/a
On Aug 10, 6:25*pm, Antoninus Twink <nos...@nospam.invalidwrote:
a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should [never] be used.
...
Of course, this is nonsense. There is a perfectly safe way to use
gets(), namely by being in control of what appears on stdin.
Heresy! I'm surprised no one launched a diatribe here
against Mr. Twink, so let me offer a diatribe in support!
Six comments on gets().
First, some history. (Some c.l.c'ers weren't
even alive at the time of the infamous Internet
Worm.)

The infamous worm was complex enough to attempt
exploitation of at least 4 different security loopholes,
but just one of the loopholes was ubiquitous enough
to make it necessary and sufficient for the Worm's
"success." That loophole was the dangerous use
of gets() in a program (fingerd) usually run with
superuser authority. It was the exploits of the
Internet Worm that led to the deprecations against
gets(). (The exploiter, IIRC, wasn't a larcenous
"black hat", but rather a "gray hat" who deliberately
aroused the Unix community from its apathy about
such bugs.)

The fingerd->gets() exploit was not trivial.
The overrun buffer was an automatic variable just
below a procedure frame, whose return-address was
modified to point to executable code within the overrun
buffer. That code loaded and ran another program
(misnamed 'sh' or 'csh') which, among other things,
executed the 'fake finger' program to exploit the
fingerd->gets() bug on still other machines.

The detailed steps of this exploit get elided in the
retelling, and programmers are left with the take-home
lesson: use gets() and the Russian mob will take
over your machine and the rest of the world.
One doesn't have to be a gets() enthusiast to note
fingerd's special nature, and that the claim that
all gets() usage risks catastrophe is confused.
Second, a confession.

Whenever I build the Index to the Fabulous Pedigree
http://fabpedigree.com/altix.htm
I do several hundred thousand gets()'s, but none of
them are "dangerous". I live with a few "dangerous"
messages during the build (although I'm sure the pedants
would prefer that each of the several hundred thousand
gets()'s produced its own such message. :-)
Perhaps there's a way to disable gcc's "dangerous"
message but, in keeping with the FSF philosophy, I'm
sure the cure is worse than the disease, something like
setenv IM_AN_UNREPENTANT_MORONIC_ASSHOLE
Third, a boast:

Since another of my "eccentric" codings, in private
throw-away code, is to *not* test malloc()'s return for
zero (failure leads to a core dump, which is what I want
anyway(*)), I'm sure that many in this ng believe that
James Dow Allen's code is buggy! I do not believe
this is the case. When I was rehired after a year to
add new support to a complete OS I wrote as a contractor
I was pleased to note that no changes had been found
necessary to my delivered code. Code reliability
doesn't require ingenuity (indeed the two may be
inversely related!); it requires conscientiousness
and avoiding the cheap substitution of dogma for thought.

AFAIK, I've never used gets() in code I've delivered
to a customer. (This is partly because most of my delivered
code has been OS or standalone, with any stdio library
calls unavailable.) I do use gets() sometimes, on
private code, when the gets()'ed string was itself
machine-produced. The gets() buffer is usually at least
ten times as large as the longest machine-produced
string. The executables are protected from the
Internet by an Impenetrable Firewall. If someone does
break into my house, intending computer mischief,
I'd be surprised if his mischief needed to invoke gets().

The gets() deprecators aren't wrong; indeed I'll cheerfully
concede that their position is more defensible than mine!
But I'm happy to take a Devil's Advocate position to
encourage critical thinking when I see the preposterous and
dogmatic over-generalizations which become so routine in
this ng. Is gets() a *potential* source of bugs? Obviously.
But I'd love to organize a wager, between me and one of
the pedants, on whose code contains more *actual* bugs.

* - Detractors will argue that what I *should* want to
do is spend hours writing a diagnostic for such malloc()
failures! In fact I don't want to do anything about them
since the smallish malloc()'s I use to build the website
Aren't Going To Fail(tm). (The pedants will respond to
this with some nonsense about how the website building
may be ported, some day, to the limited-memory chip
inside my car's fuel injection system !)
Fourth, a peeve:

fgets() preserves LineFeeds, gets() discards them.
Either behavior is fine (an application whose
stringency requires special treatment of an
"unterminated last line" probably will avoid
fgets() for other reasons anyway), but similarly-named
functions *SHOULD BEHAVE SIMILARLY*.
Assuming gets() came first and it was too late to
redefine it, fgets() should have either handled LineFeeds
the same, or have been given an obviously different name.
Whoever created the disparity in these similarly-named
functions should have done to him what Jesse J. secretly
claimed to want to do to Obama.

I *might* have changed from gets() to fgets() on some
of my private code if it weren't for the above nit.
(And yes, I *do* know how to do
if (*s == '\n') *s = 0;
in C.)
Fifth, an oft-overlooked truism:

Programming (and much real-world activity) involves
compromise between thoroughness and convenience.
strncpy(), for example, can do everything(*) strcpy()
can do, *except*, when properly coded, overrun a buffer.
In other words, the *only* reason to ever use strcpy()
(besides deliberately creating a security loophole!)
is the convenience of a 2-argument function call compared
with a 3-argument call. (* -- yes, strcpy() doesn't
null-pad. Any c.l.c'er ever write code that relied
on the *non*-padding?)

Thoroughness is not wrong, *BUT YOU SHOULD SPEND YOUR
THOROUGHNESS WISELY*. The original Hubbell Telescope
program spent $10,000 studying whether or not to do a
$3 Million test. Meanwhile the flaw, that showed up
post-launch, could have been found with a simple $50 test.
I'll bet some engineer would have done the $50 test
if not dizzied by the testing paperwork requirements
dictated by pedants.
Finally, let's note that programming and lawyerism
are different crafts.

The Authorities(tm) who post so pedantically in this
ng are often not completely wrong, but their pretentious
comments about gets() show confused thinking. In
particular, I wonder if some of them are law school
dropouts.

When I mention the gets()'s that I use, in private,
behind my Impenetrable Firewall(tm), on strings generated
by my own Bugfree Software(tm), they never acknowledge
that some gets()'s are less dangerous than others
but instead reject "safe" usages of gets() based on
pipe(fd);
dup2(fd[0], 0);
write(fd[1], "Hello world\n", 13);
printf("%s\n", gets(buff));
on grounds that the semantics of pipe(), etc. are *not
guaranteed* by the C Standard(tm).

If anyone has trouble understanding the absurdity and
hypocrisy of this legalistic view, I refer them to answers
previously given, here in the ng.

Hope this helps, :-)
James Hussein Allen
Aug 11 '08 #39

P: n/a
James Dow Allen said:
On Aug 10, 6:25 pm, Antoninus Twink <nos...@nospam.invalidwrote:
>a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should [never] be used.
...
Of course, this is nonsense. There is a perfectly safe way to use
gets(), namely by being in control of what appears on stdin.

Heresy! I'm surprised no one launched a diatribe here
against Mr. Twink,
<shrugThe guy's a troll. It is hardly surprising that he's in a whole
bunch of killfiles.
so let me offer a diatribe in support!
Hmmm.
Six comments on gets().
First, some history. (Some c.l.c'ers weren't
even alive at the time of the infamous Internet
Worm.)
You may be right - but some of us had been adults for a considerable number
of years, even as long ago as 1988. If the online CV I found for a "James
Dow Allen" is yours (which seems likely), then I can't claim to have quite
as many years under my belt as you have, but that's fine by me. :-)

<snip>
It was the exploits of the
Internet Worm that led to the deprecations against
gets().
Right.
(The exploiter, IIRC, wasn't a larcenous
"black hat", but rather a "gray hat" who deliberately
aroused the Unix community from its apathy about
such bugs.)
I think the jury's still out on that - but it's probably fair to say that
"mischief" is a better description of RTM's exploit than "malice" would
be.

<snip>
One doesn't have to be a gets() enthusiast to note
fingerd's special nature, and that the claim that
all gets() usage risks catastrophe is confused.
Yes, of course. Nevertheless, to quote Moff Tarkin's adviser, "We've
analyzed their attack pattern, and there is a danger." Since it's so easy
to use an alternative without such danger, there is no point whatsoever in
using gets().
Second, a confession.
Well, that's up to you. :-)
Third, a boast:

Since another of my "eccentric" codings, in private
throw-away code, is to *not* test malloc()'s return for
zero (failure leads to a core dump, which is what I want
anyway(*)), I'm sure that many in this ng believe that
James Dow Allen's code is buggy!
Yes. But then I believe that *everyone's* code, including mine, is buggy.
I do not believe this is the case.
Well, I have to disagree, partly on general principles and partly because
of laziness - it's far easier for me to consider your (or anyone's) code
to be buggy than to try to defend the effectively indefensible position
that it is not.

<snip>
Code reliability
doesn't require ingenuity (indeed the two may be
inversely related!); it requires conscientiousness
and avoiding the cheap substitution of dogma for thought.
True. Nevertheless, dogma /is/ cheap, and can be very effective. Because I
*always* check my mallocs (or at least, consider my failure to do so to be
a bug), I massively reduce the likelihood that my current problem
(whatever that may be) is caused by a failure to check malloc.
AFAIK, I've never used gets() in code I've delivered
to a customer.
I'm delighted to hear it. :-)

<snip>
I do use gets() sometimes, on
private code, when the gets()'ed string was itself
machine-produced.
Here's an analogy for you - any competent electrician will always use
insulated wire when doing a job *for someone else*. And I think the
anti-gets() stance in this group is intended to encourage much the same
responsible attitude - don't expose other people to unnecessary risk. But
the attitude of electricians to home projects may be different - some will
always use insulated wire, whereas some might be content to use
uninsulated wire on occasion because "I know what I'm doing, I know which
bits not to touch, and nobody else ever comes into my cellar anyway".
Whilst this isn't an attitude that I espouse or agree with, I can at least
recognise that just because someone /does/ have that attitude, it doesn't
of itself make them an idiot.

<snip>
The gets() deprecators aren't wrong; indeed I'll cheerfully
concede that their position is more defensible than mine!
Aye.
But I'm happy to take a Devil's Advocate position to
encourage critical thinking when I see the preposterous and
dogmatic over-generalizations which become so routine in
this ng.
Generalisations are always false (even this one), but often useful
nonetheless. Programmers who can't think for themselves shouldn't be
programmers - but some such people insist on programming anyway. If our
advice is "never use gets()", then those who can't think for themselves
might at least let us do their thinking for them. And those who can, will
(hopefully) take our advice seriously and then make up their own minds.
Is gets() a *potential* source of bugs? Obviously.
Right.
But I'd love to organize a wager, between me and one of
the pedants, on whose code contains more *actual* bugs.
Oh, I'm sure that my code has more bugs than yours. But they're /different/
bugs. :-)
* - Detractors will argue that what I *should* want to
do is spend hours writing a diagnostic for such malloc()
failures! In fact I don't want to do anything about them
since the smallish malloc()'s I use to build the website
Aren't Going To Fail(tm).
When they do, though, wouldn't it be more convenient for you if your
website-building program told you about them?
(The pedants will respond to
this with some nonsense about how the website building
may be ported, some day, to the limited-memory chip
inside my car's fuel injection system !)
Didn't you know? All the best Web sites are built in carburettors.
Fourth, a peeve:

fgets() preserves LineFeeds,
Yes, and you can understand why. The line might be longer than the buffer,
so there might not *be* a newline. If you discard those that you find, how
will the program know whether there was a newline or not, at a particular
point in the file?
gets() discards them.
Again, you can understand why.
Either behavior is fine (an application whose
stringency requires special treatment of an
"unterminated last line" probably will avoid
fgets() for other reasons anyway), but similarly-named
functions *SHOULD BEHAVE SIMILARLY*.
Symmetry. gets removes the newline, and puts restores it. fgets leaves the
newline (if present), so fputs doesn't need to restore it.

<snip>
Fifth, an oft-overlooked truism:

Programming (and much real-world activity) involves
compromise between thoroughness and convenience.
strncpy(), for example, can do everything(*) strcpy()
can do, *except*, when properly coded, overrun a buffer.
In other words, the *only* reason to ever use strcpy()
(besides deliberately creating a security loophole!)
is the convenience of a 2-argument function call compared
with a 3-argument call.
I have to disagree with this. I had a very, very long (but astonishingly
amicable) discussion with someone who held your view, some time ago, in
alt.comp.lang.learn.c-c++ - and he came up with a zillion arguments in
favour of strncpy over strcpy. I patiently deconstructed these arguments
one by one, and eventually (much to his credit) my correspondent
recognised that his position was indefensible, and changed his mind. But
it was a very long discussion, and I have no particular desire to re-enact
it. It'll be in the archives somewhere. (You know the newsgroup, and IIRC
my correspondent was "Chris Val", although I could be mistaken.)
(* -- yes, strcpy() doesn't
null-pad. Any c.l.c'er ever write code that relied
on the *non*-padding?)
No, but TANSTAAFL. Padding takes time. Okay, so premature optimisation is
the root of all evil - but the converse (that premature pessimisation is
the root of all virtue) has yet to be demonstrated.
Thoroughness is not wrong, *BUT YOU SHOULD SPEND YOUR
THOROUGHNESS WISELY*.
Yes. I think I do.

<snip>
Finally, let's note that programming and lawyerism
are different crafts.
Yes. A lawyer only has to persuade a judge to do things his way. A
programmer has to persuade a *computer* to do things his way. That can be
a lot more difficult, and require a much more pedantic approach.

<snip>

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 11 '08 #40

P: n/a

"James Dow Allen" <jd*********@yahoo.comschreef in bericht
news:33**********************************@i20g2000 prf.googlegroups.com...
On Aug 10, 6:25 pm, Antoninus Twink <nos...@nospam.invalidwrote:
a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should [never] be used.
...
Of course, this is nonsense. There is a perfectly safe way to use
gets(), namely by being in control of what appears on stdin.
>The infamous worm was complex enough to attempt
exploitation of at least 4 different security loopholes,
but just one of the loopholes was ubiquitous enough
to make it necessary and sufficient for the Worm's
"success."
That loophole was the dangerous use
of gets() in a program (fingerd) usually run with
superuser authority.
The story of the internet worm doesnt make Twink's statement less true.
fingerd was not in control of stdin, so yes it could be exploited. Twink
said that gets can be used safely when you are in control of stdin.

Aug 11 '08 #41

P: n/a
James Dow Allen wrote, On 11/08/08 09:38:
On Aug 10, 6:25 pm, Antoninus Twink <nos...@nospam.invalidwrote:
>>>a_03.c:(.text+0x4d): warning: the `gets' function is dangerous
and should [never] be used.
...
Of course, this is nonsense. There is a perfectly safe way to use
gets(), namely by being in control of what appears on stdin.

Heresy! I'm surprised no one launched a diatribe here
against Mr. Twink, so let me offer a diatribe in support!

Six comments on gets().
First, some history. (Some c.l.c'ers weren't
even alive at the time of the infamous Internet
Worm.)
Others were.

<snip>
Perhaps there's a way to disable gcc's "dangerous"
message but, in keeping with the FSF philosophy, I'm
sure the cure is worse than the disease, something like
setenv IM_AN_UNREPENTANT_MORONIC_ASSHOLE
I suspect the only way to disable it is to do a custom build of gcc.

<snip>
The gets() deprecators aren't wrong; indeed I'll cheerfully
concede that their position is more defensible than mine!
But I'm happy to take a Devil's Advocate position to
encourage critical thinking when I see the preposterous and
dogmatic over-generalizations which become so routine in
this ng. Is gets() a *potential* source of bugs? Obviously.
But I'd love to organize a wager, between me and one of
the pedants, on whose code contains more *actual* bugs.
I'll wager that the number of usages of gets posted to this group where
the input is not under compete control of the poster (a student is not
in control of what his/her instructor types in) is over a hundred times
more than the number of usages where it is under the posters control.
Actually, I suspect the only safe gets usages posted to this group are
posted specifically to point out that with guarantees beyond the scope
of C you can use it safely. Even on the occasions where input is under
my complete control I would use something else.
* - Detractors will argue that what I *should* want to
do is spend hours writing a diagnostic for such malloc()
failures! In fact I don't want to do anything about them
since the smallish malloc()'s I use to build the website
Aren't Going To Fail(tm). (The pedants will respond to
Actually I would not suggest spending hours on it. As it is for personal
use and you are confident it won't fail and would probably just want the
program to abort if it did you could spend a small amount of time
writing a small wrapper that checks the return value and aborts the
program with a failure message if the allocation fails. Not something I
would recommend for general programming, but better than not checking
the value and, if done at the start, will not even cost you 5 minutes.

<snip>
I *might* have changed from gets() to fgets() on some
of my private code if it weren't for the above nit.
(And yes, I *do* know how to do
if (*s == '\n') *s = 0;
in C.)
So write a wrapper function (or macro) that does this. Or (if
appropriate) you could get it to emit a diagnostic if an overlong line
is encountered.

<snip>
Finally, let's note that programming and lawyerism
are different crafts.
Reviewing code is another craft different from both of those.
The Authorities(tm) who post so pedantically in this
ng are often not completely wrong, but their pretentious
comments about gets() show confused thinking.
I disagree. I've seen more bugs more crashes of SW due to doing things
similar to calling gets (writing and using a function which takes user
input with no protection against over-long input) than I've seen safe
uses of gets. Generally when someone posts code here using gets it shows
that they have not even considered the possibility of buffer overflows,
and in such situations surely pointing out the possibility of a buffer
overflow is appropriate?
In
particular, I wonder if some of them are law school
dropouts.
I suspect none of them are.
When I mention the gets()'s that I use, in private,
behind my Impenetrable Firewall(tm), on strings generated
by my own Bugfree Software(tm), they never acknowledge
that some gets()'s are less dangerous than others
but instead reject "safe" usages of gets() based on
I've worked on safety-critical SW (as in real possibility of a person
being killed if it goes wrong) and on SW where a crash would at most
make someone mutter something, so I think I am aware that in some
situations a potential (or real) bug is more serious than in other
situations.

<snip>
If anyone has trouble understanding the absurdity and
hypocrisy of this legalistic view, I refer them to answers
previously given, here in the ng.
I don't consider the view to be hypocritical since I don't use gets in
my code (not even in throw-away code) and if I found it used in code I
was reviewing then I would reject that code.

Also see comments above on the likelihood of someone being aware of the
issues with gets when they post code here that uses it.
Hope this helps, :-)
James Hussein Allen
Here is another argument against using gets. It has now been deprecated
so you are limiting portability if you use it. After all, what with it
being deprecated it might not be available in implementations in 50
years time! ;-)
--
Flash Gordon
Aug 11 '08 #42

P: n/a
The way to get rid of the warning on gets(), if you really want to
do it, is (on FreeBSD, anyway, but I suspect it applies to other
systems that use gcc as a default compiler):

(1) Remove the call to __warn_references() in gets.c .
(2) Rebuild the C library.

Rebuilding the compiler isn't necessary.
Aug 11 '08 #43

P: n/a
Gordon Burditt wrote:
The way to get rid of the warning on gets(), if you really want to
do it, is (on FreeBSD, anyway, but I suspect it applies to other
systems that use gcc as a default compiler):

(1) Remove the call to __warn_references() in gets.c .
(2) Rebuild the C library.

Rebuilding the compiler isn't necessary.
An even easier way, and a better one to boot, is to remove
the calls to gets() from your code.

Is it possible to use gets() safely? Yes, I suppose so, in
tightly controlled circumstances. But why bother? It seems to
me that establishing the tight control is far more trouble than
just using fgets() in the first place. Any programmer for whom
the trailing '\n' is troublesome is unlikely to be able to muster
the skill and diligence to exercise the requisite control anyhow.

Something about this fascination with gets() reminds me of
the complaints one hears from people who dislike wearing safety
belts when driving. Yes, it is possible to drive safely without
a seat belt: Just don't run into anything, nor permit anything
to run into you. And look at all the buckling and unbuckling
effort you save! Yowza! Off with the belts and on with the party!

--
Er*********@sun.com
Aug 11 '08 #44

P: n/a
>
>if you can NOT define the input then I would agree. ...
Can you truly define the input? Can you guarantee that even if the code
is used in controlled conditions now, that it will NEVER be used under
different conditions?

Maybe you can, but by the time you've taken the time to do a proper
security audit of your code and all the ways it would ever be used,
it would be simpler to switch to fgets().
--
-Ed Falk, fa**@despams.r.us.com
http://thespamdiaries.blogspot.com/
Aug 11 '08 #45

P: n/a
On 11 Aug 2008 at 20:02, Eric Sosman wrote:
Something about this fascination with gets() reminds me of the
complaints one hears from people who dislike wearing safety belts when
driving.
Not really.

Usually these "complaints" are just the observation that
self-determination is a pretty fundamental liberty that we should have
in a free society. The state has *no damn business* telling me what I
should or shouldn't do in the privacy of my own car, when it doesn't
affect anyone's safety but my own.

Although Heathfield clearly would love to be the dictator of the world,
actually he isn't, and no one's trying to prevent anyone using gets() by
force of law.

So the sitations aren't really comparable.

Aug 11 '08 #46

P: n/a
On 11 Aug 2008 at 20:31, Edward A. Falk wrote:
Can you truly define the input? Can you guarantee that even if the code
is used in controlled conditions now, that it will NEVER be used under
different conditions?
Yes, I believe I can.

$ alias throwaway="rm -f"
$ throwaway throwaway-program throwaway-program.c

Or, what part of "throwaway" don't you understand?

Aug 11 '08 #47

P: n/a
Antoninus Twink wrote:
) Usually these "complaints" are just the observation that
) self-determination is a pretty fundamental liberty that we should have
) in a free society. The state has *no damn business* telling me what I
) should or shouldn't do in the privacy of my own car, when it doesn't
) affect anyone's safety but my own.

Suppose you're driving along and an oncoming car suddenly veers ondy your
lane, hitting you head-on. Wearing a seatbelt would save your life, but
that is your choice, right ? You're the only one harmed by not wearing it,
right ?

Wrong.

The person driviong that other car would, if you were killed, have the
very traumatic experience of having caused your death, as opposed to just
causing you some injuries had you worn your seatbelt.

So by choosing not to wear your seatbelt you put others in danger of being
traumatized by your death.
SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
Aug 11 '08 #48

P: n/a
Willem wrote:
Antoninus Twink wrote:
) Usually these "complaints" are just the observation
Suppose you're driving
Please don't feed the troll.

Brian
Aug 11 '08 #49

P: n/a
Willem said:
Antoninus Twink wrote:
) Usually these "complaints" are just the observation that
) self-determination is a pretty fundamental liberty that we should have
) in a free society. The state has *no damn business* telling me what I
) should or shouldn't do in the privacy of my own car, when it doesn't
) affect anyone's safety but my own.

Suppose you're driving along and an oncoming car suddenly veers ondy your
lane, hitting you head-on. Wearing a seatbelt would save your life, but
that is your choice, right ? You're the only one harmed by not wearing
it, right ?

Wrong.

The person driviong that other car would, if you were killed, have the
very traumatic experience of having caused your death, as opposed to just
causing you some injuries had you worn your seatbelt.
They might also suffer the even more traumatic experience of having you
smash through their windscreen, injuring or even killing them.
So by choosing not to wear your seatbelt you put others in danger of
being traumatized by your death.
And possibly their own.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Aug 11 '08 #50

233 Replies

This discussion thread is closed

Replies have been disabled for this discussion.