Jump to content

strlcpy

From Wikipedia, the free encyclopedia
This is an old revision of this page, as edited by Spitzak (talk | contribs) at 15:49, 16 February 2011 (Changed example to show why length is more than just a truncation indicator). The present address (URL) is a permanent link to this revision, which may differ significantly from the current revision.


In computer programming, the strlcpy function is intended to replace the function strcpy and provide a simpler and more robust and secure interface than strncpy. It is designed to copy the contents of a string from a source string to a destination string. It is almost always accompanied by the strlcat function which provides a similar alternative to strncat.

These are not C standard library functions, but are available in the libraries on several Unix operating systems, including BSD, Mac OS X, Solaris and IRIX, with notable exception of glibc on Linux.

Usage

   size_t strlcpy(char *destination, const char *source, size_t size);
   size_t strlcat(char *destination, const char *source, size_t size);

Like strncpy, strlcpy takes the destination's size as a parameter, to prevent buffer overflows (assuming the size parameter is correct). But, unlike strncpy, strlcpy always writes a NUL byte to the destination (if size is not zero). The resulting string is guaranteed to be NUL-terminated, even if this required truncation.

Secondly, strlcpy counts and returns the length of the entire source string (strncpy doesn't return a length). This length can be compared to the destination buffer's size in order to check, after the fact, whether truncation happened, or to avoid it. For example:

char stack_buffer[128]; // large enough for most strings
char* local_copy = stack_buffer;
size_t length = strlcpy(local_copy, source, sizeof(stack_buffer));
if (length >= sizeof(stack_buffer)) { // didn't fit
  local_copy = malloc(length+1); // get enough space off the heap
  strcpy(local_copy, source); // plain strcpy is safe here
}
use(local_copy, length); // work with our copy of string
if (local_copy != stack_buffer) // if we used malloc, free it
  free(local_copy);

For performance reasons, strlcpy, unlike strncpy, does not zero-fill any unused space in the destination buffer.[1]

strlcat is equivalent to doing strcat into a buffer large enough to hold the result, and then doing a strlcpy of that buffer to the destination.

History

strlcpy and strlcat were developed by Todd C. Miller and Theo de Raadt and first implemented in OpenBSD version 2.4. It has subsequently been adopted by a number of operating systems including FreeBSD (from version 3.3), Solaris and Mac OS X. Many application packages and libraries include their own copies of these functions, including glib, rsync and the Linux kernel itself.

Criticism

GNU C Library maintainer Ulrich Drepper is among the critics of the strlcpy and strlcat functions;[2] consequently these functions have not been added to glibc. Drepper argues that strlcpy and strlcat make truncation errors easier for a programmer to ignore and thus can introduce more bugs than they remove.[2] His concern with possible truncation, when using any string function involving static allocation, is shared by others.[3]

Other criticisms are that the functions are non-standard and that there are implementation differences between the BSD and Solaris implementations (the return value of strlcat, when there is no NUL in the destination buffer, differs).[4]

References

  1. ^ Todd C. Miller (1999). "strlcpy and strlcat - consistent, safe, string copy and concatenation". USENIX '99. {{cite web}}: Unknown parameter |coauthors= ignored (|author= suggested) (help)
  2. ^ a b libc-alpha mailing list, selected messages from 8 August 2000 thread: 53, 60, 61
  3. ^ Antill, James. Security with string APIs: Security relevant things to look for in a string library API
  4. ^ Antill, James. Security with string APIs