There was a question recently on SO (Why on earth would anyone use strncpy instead of strcpy?), which hade answers (answer 1, answer 2), that made me uncertain about other string functions with 'n' in their name, like snprintf
(which I have been using extensively). Is snprintf safe to use? And generally, what are the safe functions from the 'n' family?
views:
863answers:
5Beware: different platforms have different behaviors concerning null termination of a string passed to snprintf
.
snprintf does guarantee that the buffer won't be overwritten, but it does not guarantee null-termination. use sprintf_s.
See http://msdn.microsoft.com/en-us/library/2ts7cx93%28VS.71%29.aspx
strncpy()
is an oddball function that is really misnamed - it's original purpose to to ensure that a buffer was completely initialized with the contents of a string (without overflowing the target) and the reminder of the buffer with zeros. As I understand it, the original purpose was to handle file system directory entries - the target buffer was not really a string in the same sense as the other strxxx()
functions in the C library. The main problem with strncpy()
is that if the source string is larger than the destination buffer, the result will not be null terminated.
Most of the other 'n' functions that deal with strings do properly terminate the string, but there are exceptions like Microsoft's bastardized _snprintf()
. A proper C99 snprintf()
will always null terminate the destination string (as long as the destination buffer has a size greater than 0).
There's a 'Technical Report', TR 24731 that proposes a set of boundary-checking alternatives for functions that deal with strings and memory buffers. One of the goals of the TR is to have the parameters, results and error behavior of the functions be more similar across the functions. The TR seems to have somewhat mixed acceptance, and I don't think it's widely implemented other than for Microsoft's compiler (I think MS was the main driver behind the TR). you can get more information here:
- TR 24731 rationale
- TR 24731-1 (Bounds-checking interfaces)
- TR 24731-2 (Dynamic allocation functions)
Even if you're not a fan of the proposals, I think they make for educational reading about the issues with existing functions.
While snprintf
will not overrun a buffer if you give it the correct arguments, please keep in mind that it shares all of the format string vulnerabilities with other members of the *printf
family. For example, the %n
specifier is nasty because it can be used by attackers to write arbitrary bytes to arbitrary memory locations. See FIO30-C. Exclude user input from format strings from the CERT C Coding Standards wiki.