[net.lang.c] Copy strings with "strcpy", not an idiom

jdb@mordor.UUCP (John Bruner) (03/11/85)

The most portable, most readable, and often most efficient way
to copy strings is to use the string copying routines.  Then
the implementation of "strcpy" can use the fastest approach
(which may even turn out to be inline code if your compiler is
smart enough).  Attempting to save the procedure call overhead
by coding the string copy directly may be counterproductive
if you choose the wrong code sequence, or you forget to declare
your variables "register", or you move it from a VAX to a PDP-11
and there aren't enough register variables so they become "auto"
(substitute your favorite machines for "VAX" and "PDP-11"), or....
-- 
  John Bruner (S-1 Project, Lawrence Livermore National Laboratory)
  MILNET: jdb@mordor.ARPA [jdb@s1-c]	(415) 422-0758
  UUCP: ...!ucbvax!dual!mordor!jdb 	...!decvax!decwrl!mordor!jdb

ndiamond@watdaisy.UUCP (Norman Diamond) (03/14/85)

> if you choose the wrong code sequence, or you forget to declare
> your variables "register", or you move it from a VAX to a PDP-11
> and there aren't enough register variables so they become "auto"
> (substitute your favorite machines for "VAX" and "PDP-11"), or....
> --  John Bruner

I agree that the built-in procedures should be used for portability,
no matter what the language.  But if we substitute my favourite
machines, we won't run out of registers!
-- 

   Norman Diamond

UUCP:  {decvax|utzoo|ihnp4|allegra}!watmath!watdaisy!ndiamond
CSNET: ndiamond%watdaisy@waterloo.csnet
ARPA:  ndiamond%watdaisy%waterloo.csnet@csnet-relay.arpa

"Opinions are those of the keyboard, and do not reflect on me or higher-ups."

davidson@sdcsvax.UUCP (Greg Davidson) (03/16/85)

> The most portable, most readable, and often most efficient way
> to copy strings is to use the string copying routines.
> -- 
>   John Bruner (S-1 Project, Lawrence Livermore National Laboratory)

Unfortunately, the string copy routines in the standard library are
neither safe nor convenient.  strcpy is only usable if you KNOW that
overrunning is impossible.  strncpy is totally unusable because if
overrunning occurs, it may not nul terminate the destination, and
no indication is returned to allow detection of this event.

Note that the standard idiom suffers from the same insecurity as
strcpy.  And yes, I frequently encounter software which bombs because
of this, because it just assumed that filenames, etc. would be no
longer than N bytes.  Idioms are always dangerous when applied to
overrunnable or overflowable objects, because checking for these
cases always spoils the prettiness of the idiom, so programmers
don't do it.

My solution is to use my own string routines, which always take the
maximum length of the destination string as a parameter (note that
the standard strncat wants the amount of room LEFT in dst, which
usually must be calculated), and always return the number of
characters lost (if any) through truncation.

scopy(dst, room, src)			scat(dst, room, src)
  char *dst, *src;			  char *dst, *src;
  int room;				  int room;
{					{
/* Assert( room > 0 ) */		  int l = strlen(dst);
  while (--room && *src)
      *dst++ = *src++;			  return scopy( dst + l,
  *dst = '\0';						room - l,
  return strlen(src);					src );
}					}

_Greg Davidson (Virtual Infinity Systems, San Diego)

km@cadre.UUCP (03/19/85)

>Unfortunately, the string copy routines in the standard library are
>neither safe nor convenient.  strcpy is only usable if you KNOW that
>overrunning is impossible.  strncpy is totally unusable because if
>overrunning occurs, it may not nul terminate the destination, and
>no indication is returned to allow detection of this event.

YES YES YES! What is worse is that overrunning may not cause a noticeable
effect on a given machine, and the problem is not realized until the
code is ported to a second machine. When we ported the Jove sources
from vax/unix to ibm-pc/ms-dos this exact problem occurred: an incorrect use
of strncpy() resulted in an overrun with no terminal '/0': this had no
noticeable effect on the vax, but repeatedly crashed the program on the pc.
The effects of the overrun were of course on data that was referenced
far away from the actual error in the code - making debugging exceedingly
difficult.