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