Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Why is it dangerous? (http://www.velocityreviews.com/forums/t630016-why-is-it-dangerous.html)

Julian 08-10-2008 12:42 AM

Why is it dangerous?
 
'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.



Ian Collins 08-10-2008 01:03 AM

Re: Why is it dangerous?
 
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.

s0suk3@gmail.com 08-10-2008 01:39 AM

Re: Why is it dangerous?
 
On Aug 9, 7:42*pm, Julian <juli@nospam.invalid> wrote:
> '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


Keith Thompson 08-10-2008 03:20 AM

Re: Why is it dangerous?
 
Julian <juli@nospam.invalid> writes:
[...]
> #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) kst-u@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"

santosh 08-10-2008 07:57 AM

Re: Why is it dangerous?
 
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


Harald van Dijk 08-10-2008 08:22 AM

Re: Why is it dangerous?
 
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.

santosh 08-10-2008 08:25 AM

Re: Why is it dangerous?
 
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...


Ian Collins 08-10-2008 08:38 AM

Re: Why is it dangerous?
 
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.

Ben Bacarisse 08-10-2008 11:12 AM

Re: Why is it dangerous?
 
"Malcolm McLean" <regniztar@btinternet.com> writes:

> "Gordon Burditt" <gordonb.d6qjl@burditt.org> wrote 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.

Antoninus Twink 08-10-2008 11:25 AM

Re: Why is it dangerous?
 
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.



All times are GMT. The time now is 09:56 AM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.