bostic@OKEEFFE.BERKELEY.EDU (Keith Bostic) (01/07/88)
Subject: strncat is broken
Index: lib/libc/pdp/gen/strncat.s 2.10BSD
Description:
strncat(3) doesn't truncate strings correctly.
Repeat-By:
The following program demonstrates the bug.
#include <stdio.h>
#include <strings.h>
main()
{
char *s = "This is a long string, but we'll truncate it at the comma";
s[21] = '\0';
printf("%s\n", s);
strncat(s, "Arragh!!", 7);
printf("%s\n", s);
}
Fix:
Apply the following patch.
*** strncat.s.orig Wed Jan 6 11:41:24 1988
--- strncat.s Wed Jan 6 11:41:34 1988
***************
*** 36,41 ****
--- 36,42 ----
movb (r2)+,(r1)+ / copy s2 to the end of s1 stopping at the
beq 3f / end of s2 or when n runs out ...
sob r0,2b
+ clrb (r1)
3:
mov (sp)+,r2 / restore r2
4:
jpn@teddy.UUCP (John P. Nelson) (01/08/88)
>Description: > strncat(3) doesn't truncate strings correctly. Please don't "fix" this "bug". It is DOCUMENTED to work this way. If the second string is longer than the size "n" supplied, then NO NULL TERMINATER is appended. It is your MISUSE of "strncat" at fault here! I agree, it is a pain in the ass, but this is the way strncat has always worked since the beginning of C!
casey@lll-crg.llnl.gov (Casey Leedom) (01/08/88)
In article <4557@teddy.UUCP> jpn@teddy.UUCP (John P. Nelson) writes: >>Description: >> strncat(3) doesn't truncate strings correctly. > >Please don't "fix" this "bug". It is DOCUMENTED to work this way. If >the second string is longer than the size "n" supplied, then NO NULL >TERMINATER is appended. It is your MISUSE of "strncat" at fault here! No, it is a bug. I'm embarrassed as the writer of the routine to admit it. The manual page says the following: Strcat appends a copy of string s2 to the end of string s1. Strncat copies at most n characters. Both return a pointer to the null-terminated result. Since the original string is already NUL terminated, appending n characters from s2 to the end of s1 and then NUL terminating the result can really be thought of as inserting n characters just before the NUL in s1. You'll also note that both the C and VAX assembler versions NUL terminate the result when strlen(s2) > n. (Though the C version does have an error in it because it won't handle n==0 and really should stop copying one character earlier (it copies a character and then has to stomp on it with a NUL.)) Casey
rpw3@amdcad.AMD.COM (Rob Warnock) (01/08/88)
In article <4557@teddy.UUCP> you write: +--------------- | > strncat(3) doesn't truncate strings correctly. | Please don't "fix" this "bug". It is DOCUMENTED to work this way. If | the second string is longer than the size "n" supplied, then NO NULL | TERMINATER is appended. It is your MISUSE of "strncat" at fault here! | I agree, it is a pain in the ass, but this is the way strncat has | always worked since the beginning of C! +--------------- Sorry, "jpn", Keith was right the first time. The posted fix was to "strncat", NOT to "strncpy"! (Yeah, I had to look twice, myself...) True, "strncpy(dest, src, n)" does (read "MUST") leave the string unterminated if strlen(src) >= n, but "strncat(dest, src, n)" ALWAYS null-terminates (after copying at most "n" bytes). Better luck next time... ;-} Rob Warnock Systems Architecture Consultant UUCP: {amdcad,fortune,sun,attmail}!redwood!rpw3 ATTmail: !rpw3 DDD: (415)572-2607 USPS: 627 26th Ave, San Mateo, CA 94403