c equivilant to "copy"

J

jake1138

CBFalconer said:
Richard said:
CBFalconer said:
jake1138 wrote:

Wouldn't a function like this give you safety and NUL-termination?

char *mystrncpy(char *dest, const char *src, size_t size)
{
*dest = '\0';
return strncat(dest, src, size-1);
}

no. Think about it.

Ok, I've thought about it. Given

char s1[20];
char s2[]="abcdefghijklmnopqrstuvwxyz";

how is

mystrcpy(s1, s2, 20);

less safe than

strlcpy(s1, s2, 20);

mystrcpy leaves an unterminated string (no '\0') in s1, and returns
a pointer to s1, which will almost certainly lead to future
faults. strlcpy leaves a terminated string in s1, and returns 26
to indicate the size required. Since 26 >= 20 you know the output
was truncated.

I don't see how mystrncpy (it has an 'n' in it) will leave an
unterminated string. s1[0] is immediately set to '\0', then strncat
will write over that up to size-1 length then add a '\0' on the end.
I've tested this and it seems to work as expected. Please explain.
 
P

pete

Richard said:
CBFalconer said:
no. Think about it.

Ok, I've thought about it. Given

char s1[20];
char s2[]="abcdefghijklmnopqrstuvwxyz";

how is

mystrcpy(s1, s2, 20);

less safe than

strlcpy(s1, s2, 20);


mystrcpy(s1, s2, 0);

isn't safe.
 
C

CBFalconer

jake1138 said:
CBFalconer said:
Richard said:
jake1138 wrote:

Wouldn't a function like this give you safety and
NUL-termination?

char *mystrncpy(char *dest, const char *src, size_t size)
{
*dest = '\0';
return strncat(dest, src, size-1);
}

no. Think about it.

Ok, I've thought about it. Given

char s1[20];
char s2[]="abcdefghijklmnopqrstuvwxyz";

how is

mystrcpy(s1, s2, 20);

less safe than

strlcpy(s1, s2, 20);

mystrcpy leaves an unterminated string (no '\0') in s1, and returns
a pointer to s1, which will almost certainly lead to future
faults. strlcpy leaves a terminated string in s1, and returns 26
to indicate the size required. Since 26 >= 20 you know the output
was truncated.

I don't see how mystrncpy (it has an 'n' in it) will leave an
unterminated string. s1[0] is immediately set to '\0', then strncat
will write over that up to size-1 length then add a '\0' on the end.
I've tested this and it seems to work as expected. Please explain.

Sorry, I was confusing the internal action of strncat with that of
strncpy, and I just looked it up. You were right about the
safety. You don't have the advantage of getting back the length
info that strlcpy/cat provide.
 
M

Michael Wojcik

I don't see how mystrncpy (it has an 'n' in it) will leave an
unterminated string.

In the normal case it won't. Perhaps Chuck is thinking that strncat
has the same brain-dead behavior as strncpy when the copy length is
smaller than the source length; it doesn't. (It has other
infelicities.)

However, mystrncpy still has problems:

- As Chuck noted, it doesn't tell you if truncation occurred, unlike
strlcpy. This isn't a bug, but one could argue that it makes
mystrncpy inferior to strlcpy. (Some prefer returning the
destination string for "chaining" purposes.)

- If size == 0, you're in trouble.

- If I were writing "safe" versions of the string-handling functions,
you can be damn sure that I'd have them do something sensible with
null arguments.

--
Michael Wojcik (e-mail address removed)

Pocket #9: A complete "artificial glen" with rocks, and artificial moon,
and forester's station. Excellent for achieving the effect of the
sublime without going out-of-doors. -- Joe Green
 
J

jake1138

Michael said:
In the normal case it won't. Perhaps Chuck is thinking that strncat
has the same brain-dead behavior as strncpy when the copy length is
smaller than the source length; it doesn't. (It has other
infelicities.)

However, mystrncpy still has problems:

- As Chuck noted, it doesn't tell you if truncation occurred, unlike
strlcpy. This isn't a bug, but one could argue that it makes
mystrncpy inferior to strlcpy. (Some prefer returning the
destination string for "chaining" purposes.)

- If size == 0, you're in trouble.

- If I were writing "safe" versions of the string-handling functions,
you can be damn sure that I'd have them do something sensible with
null arguments.

--
Michael Wojcik (e-mail address removed)

Pocket #9: A complete "artificial glen" with rocks, and artificial moon,
and forester's station. Excellent for achieving the effect of the
sublime without going out-of-doors. -- Joe Green

All good points, from everyone. I didn't think about size==0, that
should be checked. Also, to make this work like strlcpy, I'd have to
use strlen, which would make it slower. Or do the copy manually with a
count, which I assume strlcpy does. I'll take a look at the
implementation of strlcpy.
 
R

Richard Bos

- If I were writing "safe" versions of the string-handling functions,
you can be damn sure that I'd have them do something sensible with
null arguments.

strlcpy() silently and transparently covers up the bug of using a null
pointer as if it were a string - I wouldn't call that "something
sensible". I'd rather catch my bugs now rather than when the program has
gone into production.

Richard
 
M

Michael Wojcik

strlcpy() silently and transparently covers up the bug of using a null
pointer as if it were a string - I wouldn't call that "something
sensible". I'd rather catch my bugs now rather than when the program has
gone into production.

It's only a bug if it's a violation of the design. If by design
my program uses null character pointers and empty strings
interchangeably in some contexts, then there's nothing wrong with
the behavior of strlcpy in those contexts.

And, of course, "something sensible" could be aborting. What's not
sensible is UB. I can accept that the standard left behavior
undefined for strcpy et al, because that could be useful for
optimized implementations, but if I'm writing my own functions I
check parameters.

Frankly, it's exceedingly rare that one of the functions in any of
my current projects flags an invalid parameter - that indicates a
logic error in the caller. But it gets handled cleanly, and the
program - which is certainly doing other things, unrelated to the
error - continues running. That's far better than UB.

--
Michael Wojcik (e-mail address removed)

Duck: No secret what's worth a hoot ought to be kept quiet.
Pogo: Secrets is usually perty doggone fascinatin'.
Duck: Egg-zackly ... it's completely illogical to keep a secret secret.
Pogo: An' unfair. -- Walt Kelly
 

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
474,183
Messages
2,570,969
Members
47,524
Latest member
ecomwebdesign

Latest Threads

Top