gets() - dangerous?

C

Christian Bau

Richard Heathfield said:
I fixed a small part of the Wiki's C article, rendering the text more
accurate than before. Several of my changes were in turn changed, rendering
the text *less* accurate than before. I don't have time to play those
games.

Just had a look at the article, just out of curiosity. It is just good
for a laugh. If you went through it using the correct principle that the
"C Language" is the language as defined by the current standard, which
is the C99 Standard, and change everything accordingly, then some people
will suffer from a heart attack.
 
M

Markus Becker

James Dow Allen said:
input, but there are *lots* and *lots* of code fragments that suffer
from the same "danger" as gets()

Such as?

I mean, besides fragments from your own programs. Surely people
used to using gets() without thought will write their own routines
in the same broken way. BIIIIG buffers (predictable, known input,
but just in case ...), never _ever_ check a return value of a
function (you know all your calls succeed, because of 'predictable'
input, yeah, I know, besides: what to do in case of an error?
Program termination due to some sort of crash is just as good
as anything). Another benefit of 'known', 'predictable' input
is the lack of need to check you input, because you know it
will fit because your buffer is big enough, just in case ...

I have no right to stop people from trying out dangerous
things at home, nevertheless I think that someone who
does not take on a seatbelt because he 'knows' that he
'never' will be involved in an accident. But you stop
every now and then to prevent your car from getting too
fast and you have an ejection seat, just in case ...

Markus
 
M

Markus Becker

Hmmm ... here's a rhetorical question. What is the value of a
specifying a function in the language definition if you can't even use
it -- not ever?

Despite it being a rhetorical question, here's an answer:

Some ill-meaning people insist on telling the story that
K&R designed the C programming language as one evil big
practical that unfortunately has gotten out of control.
something like that. I still don't know who exactly is pulling for the
continued support for this function, but they seem to have a lot of
influence over compiler vendors and the standards committee.

Definitely more so than they have a feeling for the needs and
wishes of programmers. But backward compatibility (even of
security holes) is a Holy Grail.

Or perhaps it's the NSA, insisting that every programming
language has to have a hole where they can sneak in...

Markus
 
D

Deiter

Christian said:
Just had a look at the article, just out of curiosity. It is just good
for a laugh. If you went through it using the correct principle that the
"C Language" is the language as defined by the current standard, which
is the C99 Standard, and change everything accordingly, then some people
will suffer from a heart attack.

Someone edited it less than an hour ago. Way to go.. :)

[ http://en.wikipedia.org/wiki/C_programming_language]

This page was last modified 00:14, 3 January 2006.
 
M

Markus Becker

Emmanuel Delahaye said:
What prevents us to edit the text in a more balanced way ?

The fear or even knowledge that it may not be worth the effort?

I always try to make changes in such a way, that a potential 'reverter'
gets (oh man, this 'gets' gets me everywhere tonight) at least a hint on
where or why he was wrong.

I just edited the "x is equivalent to *(x + i*sizeof(x))"
crap in the section "unification of arrays and pointers".

I tried to do my best, but I'm still not completely
satisfied with the paragraph. Especially the end of it, which in fact
just repeats what has been said two or three sentences before,
but in a way that could give new insight to a potential reader,
so I didn't change it (yet).
Il have made
some modifications myself.

I'm glad that you reverted some of them yourself ;-)
It's simple and easy.

Sure, but the '*(x + i*sizeof(x))' error escaped you. :)
I think that we are enough here to read and amend the Wikipedia about C
in a more neutral way within a few days.

I'm afraid that there are enough morons out there to try and vandalize
it back to it's actual crappy state within even fewer days. And I'm afraid
(or glad, that depends ;-) that I've better and more important things to do.

Better as in 'better suited to earn my living' ...

There are lives that depend on the quality of my work.
One that is particularly valuable to me is my own.

BTW, isn't there a better place to discuss this?
The discussion page of the article could be a starting place.

Markus
 
R

Richard Heathfield

Markus Becker said:
Yes, for the same exact reasons: it is dangerous and alternatives
(here: strncpy) exists.

strcpy is *not* dangerous if used correctly, whereas gets is.
strncpy is *not* a plug-in replacement for strcpy.
strncpy is *not* safer than strcpy.
 
C

Christian Bau

Richard Heathfield said:
Markus Becker said:


strcpy is *not* dangerous if used correctly, whereas gets is.
strncpy is *not* a plug-in replacement for strcpy.
strncpy is *not* safer than strcpy.

strncpy contains two wonderful traps:

1. strncpy fills the destination beyond the length of the copied string
with zeroes. If you have a big buffer, then this is costly. Copying a
million short strings with strcpy is no sweat, copying them into a 5 MB
buffer with strncpy will take an hour.

2. If the destination buffer is not large enough for the source string,
there will be no trailing zero anywhere in the destination. In other
words, the result is not a valid C string. Using it anywhere is asking
for trouble. For example

char buffer1 [10];
char buffer2 [20];
char* p = "Hello, world!");

strncpy (buffer1, p, sizeof (buffer1));
strncpy (buffer2, buffer1, sizeof (buffer2));

invokes undefined behavior.
 
M

Markus Becker

Richard Heathfield said:
strcpy is *not* dangerous if used correctly, whereas gets is.

You're right, there's no chance to use gets in a way that
makes it safe. But strcpy can be used in an unsafe way, the
safe way would be to check if the length of the source
string does not exceed the available size of the destination
buffer and act accordingly if it does. The 'alternative'
would be to use strncpy with an n of one less than the
capacity of the destination.

When I read the man pages regarding gets and strcpy,
they mention BUGS and dangerous and such in the case
of gets -> this is clearly dangerous.
In the case of strcpy I read "the buffer that dst points
to has to be big enough and the too strings must not
overlap" -> this _can_ be made safe, but it is tedious(sp?).

In my 'definition' that a hint that there are a few traps
and for this reason it makes strcpy potentially dangerous
for me. But as I know you and your skills, I'm eager
to learn something... and I', quite sure you come up
with a solution or explanation that I haven't thought
of yet.

So what do you mean by 'if used correctly' regarding both
strcpy and gets? IMHO the only 'correct' use of gets
it to NOT use gets. Never. There are several possibilities
to use strcpy correctly, but all involve calls to other
functions, an "if ()" and an "else strncpy(...)", checking
if the strings overlap or not and so on..

So why not use strncpy all times?

Because your environment is so that you _know_ that
src fits in dst, e.g. when both buffers are of the
same size and it _can't_ be that src is longer than
dst can hold?

Then gets is safe, too. Namely when I can be sure that
the length of the string that gets will read from
stdin will fit into my buffer, e.g. when some file
of known structure or the output of a program that
guarantees the length of its output does not exceed
a given value is connected to my stdin.

But I'm sure that you cannot mean this.
strncpy is *not* a plug-in replacement for strcpy.

Who claimed that it was? I said it is an alternative,
because IMHO it is similar enough.
And in this same way fgets relates in my world to gets:
Use it instead, give it the length of your destination
buffer and stdin as FILE*, so it is an 'alternative'.
strncpy is *not* safer than strcpy.

Sure, one can use it with unsafe parameters as well.
strcpy w/o context is no more dangerous than strncpy, both can
be used in safe and unsafe ways. But you can predict its behaviour
and control it because all information is available before the
call to any of those both functions. I also agree that gets is
unsafe and there is no way to make it safe, but:

Since I work in the evil world outside, where I have to make
sure that code that is produced by me or programmers that I'm res-
ponsible for _is_ safe, and will stay safe, I have
a slightly different notion of 'safe' than you have.

It's more easy to enforce a coding rule regarding string copying
that reads like this:

Always use "strncpy(dst,src,CAPACITY_OF_DST-1);"

as compared to this:

if (strlen(src)<=CAPACITY_OF_DST) strcpy(dst,src);
else /* do something accordingly, which will be: */
strncpy(...);

So for 'me', strncpy is safer than strcpy and if I try to use
strcpy correctly I will need to program a call to strncpy anyway
if the length of src gets (oh my, this word again) greater than
the capacity of the buffer pointed to by dst.

What would be the 'proven' way of using strcpy in a safe
way without needing strncpy as a fallback? I wouldn't be
surprised if I had overlooked something obvious. Sometimes
I cannot see the wood for the trees, you know. Especially
after a long night like this...

Markus
 
N

Netocrat

On Tue, 03 Jan 2006 10:27:28 +0100, Markus Becker wrote:
[arguing by example that strncpy is safer than strcpy]
It's more easy to enforce a coding rule regarding string copying that
reads like this:

Always use "strncpy(dst,src,CAPACITY_OF_DST-1);"

This has the overhead of copying (CAPACITY_OF_DST - 1 - strlen(src)) zero
bytes /every/ time the destination buffer's capacity is greater than the
source string's length (plus terminating '\0').

It also silently truncates strings that are oversize: this semantic is not
universally appropriate. I'd say then that the above snippet is less safe
than the one below, since you have no opportunity to take other action on
oversize strings.
as compared to this:

if (strlen(src)<=CAPACITY_OF_DST) strcpy(dst,src);

....which avoids the redundant copying overhead. Often the call to
strlen(src) is required for a prior operation and its result is at hand
anyhow. (the comparison shouldn't include an equality test btw)
else /* do something accordingly, which will be: */
strncpy(...);

Well, if truncating the string is appropriate semantics, then fine.
Another possibility that may be appropriate is to (re)assign a buffer
large enough to hold the string. At least this code snippet gives you the
opportunity to take that action.

[...]
What would be the 'proven' way of using strcpy in a safe way without
needing strncpy as a fallback? I wouldn't be surprised if I had
overlooked something obvious.

Perhaps the obvious in some situations is as you've written, and taking
whatever error action is appropriate if a (re)assignment of a large enough
buffer fails in the 'else' branch. That action might be to print an
out-of-mem warning, log to a file, ask the user whether they want to
retry, etc.

[...]
 
T

Targeur fou

Christian Bau wrote:

Hello,
Richard Heathfield said:
Markus Becker said:


strcpy is *not* dangerous if used correctly, whereas gets is.
strncpy is *not* a plug-in replacement for strcpy.
strncpy is *not* safer than strcpy.

strncpy contains two wonderful traps:

1. strncpy fills the destination beyond the length of the copied string
with zeroes. If you have a big buffer, then this is costly. Copying a
million short strings with strcpy is no sweat, copying them into a 5 MB
buffer with strncpy will take an hour.

2. If the destination buffer is not large enough for the source string,
there will be no trailing zero anywhere in the destination. In other
words, the result is not a valid C string. Using it anywhere is asking
for trouble. For example

char buffer1 [10];
char buffer2 [20];
char* p = "Hello, world!");

strncpy (buffer1, p, sizeof (buffer1));
strncpy (buffer2, buffer1, sizeof (buffer2));

invokes undefined behavior.

Agreed.

To avoid the dangers of the two points above, I would use something
like this in my programs:

#define MAXCH_BUF1 10
#define MAXCH_BUF2 20

char buffer1 [ MAXCH_BUF1 + 1 ];
char buffer2 [ MAXCH_BUF2 + 1 ];
size_t lngSrc = 0, lngDst = 0;

char* p = "Hello, world!";

lngSrc = strlen(p);
lngDst = (lngSrc > MAXCH_BUF1 ) ? MAXCH_BUF1 : lngSrc ;
strncpy (buffer1, p, lngDst+1);

lngSrc = strlen(buffer1);
lngDst = (lngSrc > MAXCH_BUF2 ) ? MAXCH_BUF2 : lngSrc ;
strncpy (buffer2, buffer1, lngDst+1);

I don't really understand the religious war between strcpy/strncpy pros
and cons since it's not really difficult for an experienced programmer
to write a safe program with one or the other.
Discussions about strcpy() and strncpy() often (always?) concern the
technical point of view but rarely the functional point of view. I
don't think strncpy() was designed to solve the lacks of strcpy() nor
to prevent a buffer overflow. At first glance for me, strncpy() seems
to be the easy way to extract a "real" subset of a string, whereas it's
an evidence that strcpy() was first designed for string copy, although
it's also possible with strcpy to extract a subset of a string from a
given starting position until the end.

Regis
 
T

Targeur fou

Markus said:
Hello,

You're right, there's no chance to use gets in a way that
makes it safe. But strcpy can be used in an unsafe way, the
safe way would be to check if the length of the source
string does not exceed the available size of the destination
buffer and act accordingly if it does. The 'alternative'
would be to use strncpy with an n of one less than the
capacity of the destination.

Perhaps, but you still have the first trap explained by Christian.
When I read the man pages regarding gets and strcpy,
they mention BUGS and dangerous and such in the case
of gets -> this is clearly dangerous.

I agree for gets() but not for strcpy().
In the case of strcpy I read "the buffer that dst points
to has to be big enough and the too strings must not
overlap" -> this _can_ be made safe, but it is tedious(sp?).

The two strings must not overlap too with strncpy().
In my 'definition' that a hint that there are a few traps
and for this reason it makes strcpy potentially dangerous
for me. But as I know you and your skills, I'm eager
to learn something... and I', quite sure you come up
with a solution or explanation that I haven't thought
of yet.

So what do you mean by 'if used correctly' regarding both
strcpy and gets? IMHO the only 'correct' use of gets
it to NOT use gets. Never.

I would'nt compare gets() and strcpy(). gets() shall not be used, it
involves the standard input stream with which the programmer hasn't
necessary the possibility to know the "maximum size", therefore he
doesn't have enough informations to use gets() securely.
There are several possibilities
to use strcpy correctly, but all involve calls to other
functions, an "if ()" and an "else strncpy(...)", checking
if the strings overlap or not and so on..

Question: why would you use strncpy() in your else branch? What is
better, obtaining a truncated string or not doing the copy? In fact,
it's not a technical problem but a functional one. There are many cases
where I would prefer not doing the copy .
So why not use strncpy all times?

Because it's possible to use strcpy () correctly without much more
pain.
Because your environment is so that you _know_ that
src fits in dst, e.g. when both buffers are of the
same size and it _can't_ be that src is longer than
dst can hold?

Then gets is safe, too. Namely when I can be sure that
the length of the string that gets will read from
stdin will fit into my buffer, e.g. when some file
of known structure or the output of a program that
guarantees the length of its output does not exceed
a given value is connected to my stdin.

But I'm sure that you cannot mean this.


Who claimed that it was? I said it is an alternative,
because IMHO it is similar enough.
And in this same way fgets relates in my world to gets:
Use it instead, give it the length of your destination
buffer and stdin as FILE*, so it is an 'alternative'.


Sure, one can use it with unsafe parameters as well.
strcpy w/o context is no more dangerous than strncpy, both can
be used in safe and unsafe ways. But you can predict its behaviour
and control it because all information is available before the
call to any of those both functions. I also agree that gets is
unsafe and there is no way to make it safe, but:

Since I work in the evil world outside, where I have to make
sure that code that is produced by me or programmers that I'm res-
ponsible for _is_ safe, and will stay safe, I have
a slightly different notion of 'safe' than you have.

It's more easy to enforce a coding rule regarding string copying
that reads like this:

Always use "strncpy(dst,src,CAPACITY_OF_DST-1);"

as compared to this:

if (strlen(src)<=CAPACITY_OF_DST) strcpy(dst,src);
else /* do something accordingly, which will be: */
strncpy(...);

So for 'me', strncpy is safer than strcpy and if I try to use
strcpy correctly I will need to program a call to strncpy anyway
if the length of src gets (oh my, this word again) greater than
the capacity of the buffer pointed to by dst.

What would be the 'proven' way of using strcpy in a safe
way without needing strncpy as a fallback? I wouldn't be
surprised if I had overlooked something obvious. Sometimes
I cannot see the wood for the trees, you know. Especially
after a long night like this...

I don't understand why strncpy() is absolutely need as a fallback. It
could be something else, like an error-handling mechanism due to the
detected buffer overflow. It's easier to detect a buffer overflow that
checking if a string contains all the needed characters for a further
functional task in the program. You may have cases where obtaining
truncated strings is undesirable.

Regis
 
?

=?iso-8859-1?q?Dag-Erling_Sm=F8rgrav?=

Markus Becker said:
Always use "strncpy(dst,src,CAPACITY_OF_DST-1);"

This is not much safer than strcpy() (it does not warn you of
overflow, and sooner or later you *will* forget the -1).

if (snprintf(dst, len, "%s", src) >= len) {
fprintf(stderr, "overflow!\n");
exit(EXIT_FAILURE);
}

DES
 
N

Netocrat

This is not much safer than strcpy() (it does not warn you of
overflow,

It's written to avoid overflows, not to warn about them.
and sooner or later you *will* forget the -1).

if (snprintf(dst, len, "%s", src) >= len) {

The damage has already been done by this point: a skilled/lucky cracker
might have replaced the following code with something a lot more insidious
than a warning message and exit.
 
C

Christian Bau

"Targeur fou said:
Christian Bau wrote:

Hello,
Richard Heathfield said:
Markus Becker said:


Or do you
think strcpy() should be barred also?

Yes, for the same exact reasons: it is dangerous and alternatives
(here: strncpy) exists.

strcpy is *not* dangerous if used correctly, whereas gets is.
strncpy is *not* a plug-in replacement for strcpy.
strncpy is *not* safer than strcpy.

strncpy contains two wonderful traps:

1. strncpy fills the destination beyond the length of the copied string
with zeroes. If you have a big buffer, then this is costly. Copying a
million short strings with strcpy is no sweat, copying them into a 5 MB
buffer with strncpy will take an hour.

2. If the destination buffer is not large enough for the source string,
there will be no trailing zero anywhere in the destination. In other
words, the result is not a valid C string. Using it anywhere is asking
for trouble. For example

char buffer1 [10];
char buffer2 [20];
char* p = "Hello, world!");

strncpy (buffer1, p, sizeof (buffer1));
strncpy (buffer2, buffer1, sizeof (buffer2));

invokes undefined behavior.

Agreed.

To avoid the dangers of the two points above, I would use something
like this in my programs:

#define MAXCH_BUF1 10
#define MAXCH_BUF2 20

char buffer1 [ MAXCH_BUF1 + 1 ];
char buffer2 [ MAXCH_BUF2 + 1 ];
size_t lngSrc = 0, lngDst = 0;

char* p = "Hello, world!";

lngSrc = strlen(p);
lngDst = (lngSrc > MAXCH_BUF1 ) ? MAXCH_BUF1 : lngSrc ;
strncpy (buffer1, p, lngDst+1);

lngSrc = strlen(buffer1);
lngDst = (lngSrc > MAXCH_BUF2 ) ? MAXCH_BUF2 : lngSrc ;
strncpy (buffer2, buffer1, lngDst+1);

Doesn't make much difference. You still get undefined behavior.

The more dangerous problem with strncpy is: If the destination buffer is
not large enough, what it copies _is not a valid C string_!!! It doesn't
append a trailing zero! If you use strncpy to copy into a 10 byte
buffer, and the source string is too long, it copies 10 bytes instead of
copying 9 bytes and a trailing zero, which at least would have given you
a valid C string.

I guess it is time to write your own function that does what it should
do: strcpy if the result fits, copy a valid C string by dropping
trailing characters if the result doesn't fit. You still have to be
careful, but at least you won't get a buffer overflow and undefined
behavior.
 
C

Chuck F.

Targeur said:
.... snip ...

I don't really understand the religious war between
strcpy/strncpy pros and cons since it's not really difficult for
an experienced programmer to write a safe program with one or
the other. Discussions about strcpy() and strncpy() often
(always?) concern the technical point of view but rarely the
functional point of view. I don't think strncpy() was designed
to solve the lacks of strcpy() nor to prevent a buffer overflow.
At first glance for me, strncpy() seems to be the easy way to
extract a "real" subset of a string, whereas it's an evidence
that strcpy() was first designed for string copy, although it's
also possible with strcpy to extract a subset of a string from a
given starting position until the end.

It is especially fou since strlcpy (and strlcat) were invented to
solve this sort of problem. Although non-standard, they are easily
implemented using only standard coding. Some systems already
include them. My implementation is available at:

<http://cbfalconer.home.att.net/download/strlcpy.zip>

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
 
D

David Resnick

Targeur said:
To avoid the dangers of the two points above, I would use something
like this in my programs:

#define MAXCH_BUF1 10
#define MAXCH_BUF2 20

char buffer1 [ MAXCH_BUF1 + 1 ];
char buffer2 [ MAXCH_BUF2 + 1 ];
size_t lngSrc = 0, lngDst = 0;

char* p = "Hello, world!";

lngSrc = strlen(p);
lngDst = (lngSrc > MAXCH_BUF1 ) ? MAXCH_BUF1 : lngSrc ;
strncpy (buffer1, p, lngDst+1);

lngSrc = strlen(buffer1);
lngDst = (lngSrc > MAXCH_BUF2 ) ? MAXCH_BUF2 : lngSrc ;
strncpy (buffer2, buffer1, lngDst+1);

I don't really understand the religious war between strcpy/strncpy pros
and cons since it's not really difficult for an experienced programmer
to write a safe program with one or the other.
Discussions about strcpy() and strncpy() often (always?) concern the
technical point of view but rarely the functional point of view. I
don't think strncpy() was designed to solve the lacks of strcpy() nor
to prevent a buffer overflow. At first glance for me, strncpy() seems
to be the easy way to extract a "real" subset of a string, whereas it's
an evidence that strcpy() was first designed for string copy, although
it's also possible with strcpy to extract a subset of a string from a
given starting position until the end.

Um, given that you are precomputing the length once with strlen, why
do it again with str(n)cpy? Usually memcpy/memmove is the right
thing given a length in hand. strncpy is (as said upthread) a pain to
use
because of its flaws. And strcpy is rarely right either because of
buffer
overflow woes -- if you know the length of the source, use mem.cpy .
If you don't know the length, use of strcpy is not safe.

-David
 
T

Targeur fou

Christian said:
Targeur fou said:
Christian Bau wrote:

Hello,
Markus Becker said:


Or do you
think strcpy() should be barred also?

Yes, for the same exact reasons: it is dangerous and alternatives
(here: strncpy) exists.

strcpy is *not* dangerous if used correctly, whereas gets is.
strncpy is *not* a plug-in replacement for strcpy.
strncpy is *not* safer than strcpy.

strncpy contains two wonderful traps:

1. strncpy fills the destination beyond the length of the copied string
with zeroes. If you have a big buffer, then this is costly. Copying a
million short strings with strcpy is no sweat, copying them into a 5 MB
buffer with strncpy will take an hour.

2. If the destination buffer is not large enough for the source string,
there will be no trailing zero anywhere in the destination. In other
words, the result is not a valid C string. Using it anywhere is asking
for trouble. For example

char buffer1 [10];
char buffer2 [20];
char* p = "Hello, world!");

strncpy (buffer1, p, sizeof (buffer1));
strncpy (buffer2, buffer1, sizeof (buffer2));

invokes undefined behavior.

Agreed.

To avoid the dangers of the two points above, I would use something
like this in my programs:

#define MAXCH_BUF1 10
#define MAXCH_BUF2 20

char buffer1 [ MAXCH_BUF1 + 1 ];
char buffer2 [ MAXCH_BUF2 + 1 ];
size_t lngSrc = 0, lngDst = 0;

char* p = "Hello, world!";

lngSrc = strlen(p);
lngDst = (lngSrc > MAXCH_BUF1 ) ? MAXCH_BUF1 : lngSrc ;
strncpy (buffer1, p, lngDst+1);

lngSrc = strlen(buffer1);
lngDst = (lngSrc > MAXCH_BUF2 ) ? MAXCH_BUF2 : lngSrc ;
strncpy (buffer2, buffer1, lngDst+1);

Doesn't make much difference. You still get undefined behavior.

Oops, you're right. I answered too quickly.

Correction of the code above:
/*...*/
strncpy (buffer1, p, lngDst);
buffer1[lngDst] = '\0';
/*...*/
strncpy (buffer2, buffer1, lngDst);
buffer2[lngDst] = '\0';

Not so simple to write correct C code...

Regis
 
M

Markus Becker

Markus Becker said:
Some ill-meaning people insist on telling the story that
K&R designed the C programming language as one evil big
practical that unfortunately has gotten out of control.
^
joke
 
M

Markus Becker

Targeur fou said:
Markus Becker wrote:

Perhaps, but you still have the first trap explained by Christian.

Ok, but then, consequentially, every function concerning
C-strings (null-terminated char arrays) should be considered
to have traps. And many more. What about system()?
Just kidding ...
The two strings must not overlap too with strncpy().

I know[1], violating this constraint might produce garbled
data (could be dangerous, too, depending on what you
do with the data afterwards) but will definitely _not_
produce a buffer overflow in the sense that anything
outside of src or dst gets overwritten. Not in a good
world and not in an evil one.

[1] it just happened to be written that way in the combined
man page for strcpy and strncpy and I translated that
from german to illustrate the fact that gets speaks
of BUGS, ... and strcpy speaks of the size of dst
must be big enough and strncpy and strcpy both assume
that the buffers don't overlap.
I would'nt compare gets() and strcpy(). gets() shall not be used, it

'shall' in the sense as it is meant in the standard?
Ok, I think we have settled that, now lets forget gets.
Question: why would you use strncpy() in your else branch? What is

Because I want to get the data and not give up because some
circumstances not under my control happen to 'attack' me.
(I'm imagining apache2 here that would die every time
some script-kiddie tries to overflow its input buffer for
the http-requests which happens to be 8192 chars long. Instead
it warns me and prints the first xy chars of the request and
related information to the error.log)
better, obtaining a truncated string or not doing the copy? In fact,

That depends on the application.
Normally, I try to design my programs in such a way that
they work. In my world this does not mean to return EXIT_FAILURE
if I detect that the buffer is too small. I would fragment the
data (if possible without corrupting them) and then call strncpy
again until I got all of src.

And with work I mean this 'degrade gracefully' thing.
it's not a technical problem but a functional one. There are many cases
where I would prefer not doing the copy .
Agreed.

Because it's possible to use strcpy () correctly without much more
pain.

How? HOW!!!1
I don't understand why strncpy() is absolutely need as a fallback. It

Not absolutely, but if I want to work on the data even if my destination
buffer is too small.
functional task in the program. You may have cases where obtaining
truncated strings is undesirable.

Yes, and there are cases where it is just plain silly to report
a 'buffer overflow' which just has not happend yet and can be
worked around. Another solution could be to realloc the dst
and try again, this time with strcpy because I ... oh, my,
it's beginning to get clear. Sure, there are hundreds of
way to use strcpy correctly, one of them being:

char *dst = malloc(strlen(src));
if (dst) strcpy(dst,src);

I think we can stop here, everything depends far too much
on the circumstances. But I see clear solutions and I withdraw
my claim that strcmp is dangerous and now happily claim the
opposite ;-)

At this point most of my post has been rendered needless but
since I typed it anyway, I'll leeave my 'argumentation' there
for your amusement.

Thanks, really!

Markus
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top