|
From: Randall H. <lis...@ch...> - 2003-08-12 16:38:03
|
If you do this: char dest[64]; char src [16]; strcpy( dest, "more" ); strcpy( src, " stuff" ); strncat( dest, src, sizeof(dest) - strlen(dest) - 1 ); Valgrind says: Source and destination overlap in strncat(0x44b45b98, 0x44b45b88, 59) It's clear what's going on. Memory is layed out like this: [0..15 src][0..63 dst] and valgrind, not knowing whether src is null terminated, is concerned that strncat might read past the end of src into dst. This isn't an error in this case. But I'm on the wall as to whether valgrind should flag it or not. Any thoughts? I guess it boils down to whether valgrind would detect the overwrite through other means if it occured, or could check for null termination before reporting an error. P.S. Yes, this was expanded from a "safe strcat" macro. Just tracing it down. Thanks, Randall |
I sent a bug report about this to the author a few days ago. It's
definitely not right. Here's my patch, based on what strncat() does.
--- mac_replace_strmem.c 2003/08/07 02:52:24 1.1
+++ mac_replace_strmem.c 2003/08/07 02:56:35
@@ -186,13 +186,15 @@
char* strncpy ( char* dst, const char* src, int n )
{
- Char* dst_orig = dst;
+ const Char* src_orig = src;
+ Char* dst_orig = dst;
Int m = 0;
- if (is_overlap(dst, src, n, n))
- complain3("strncpy", dst, src, n);
-
while (m < n && *src) { m++; *dst++ = *src++; }
+ /* Check for overlap after copying; all n bytes of dst are elevant,
+ but only m+1 bytes of src if terminator was found */
+ if (is_overlap(dst_orig, src_orig, n, (m < n) ? m+1 : n))
+ complain3("strncpy", dst, src, n);
while (m++ < n) *dst++ = 0; /* must pad remainder with nulls */
return dst_orig;
|