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?
-
1Related: beware the different behaviors of snprintf/swprintf/snwprintf/etc and %ls and %s on different platforms. They are all different. – Jared Oberhaus Aug 13 '09 at 06:52
-
Only on broken, non-conformant implementations. The C standard is very clear on what these format specifiers are supposed to do. – R.. GitHub STOP HELPING ICE Aug 11 '10 at 17:11
5 Answers
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.

- 333,147
- 50
- 533
- 760
-
1As an aside, the MS implementation is non-conforming. http://stackoverflow.com/questions/372980/do-you-use-the-tr-24731-safe-functions – Deduplicator Feb 19 '15 at 22:30
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.

- 22,195
- 6
- 45
- 72
It is safe as you long as you provide the correct length for the buffer.

- 12,034
- 24
- 73
- 85
-
Which length you provide (and whether or not you manually null terminate the end of the buffer yourself) depends on which platform you're on. – Jared Oberhaus Aug 13 '09 at 06:53
snprintf does guarantee that the buffer won't be overwritten, but it does not guarantee null-termination. You can use sprintf_s
on MSVC if you're willing to be non-standard.
See http://msdn.microsoft.com/en-us/library/2ts7cx93(VS.71).aspx

- 4,168
- 20
- 23
-
1Actually not, snprintf doesn't guarantees buffer overflows at all. It depends on the buffer size you provided, which can be incorrect – akif Aug 13 '09 at 06:52
-
It goes without saying that there is no CRT function that magically knows how big the buffer passed in actually is. – Drew Hoskins Aug 13 '09 at 07:39
-
2Well, then it goes without saying that no CRT function is "safe", and there's not much point people going around pretending that appending _s to the names of them all breaks this rule ;-) – Steve Jessop Aug 13 '09 at 10:45
-
6-1: You should clarify that you're talking about the broken Microsoft implementation and not the C standard. – R.. GitHub STOP HELPING ICE Aug 11 '10 at 17:10
Beware: different platforms have different behaviors concerning null termination of a string passed to snprintf
.

- 14,547
- 4
- 56
- 55
-
6`snprintf` as specified in ISO C99 is guaranteed to null-terminate. – Pavel Minaev Aug 13 '09 at 06:47
-
1That's what ISO C99 says: however, the behavior on certain platforms is different. You'll have to experiment and validate each platform to be sure. – Jared Oberhaus Aug 13 '09 at 06:49
-
3Can you give an example of a platform that doesn't conform with standard C in this respoect? – Martin v. Löwis Aug 13 '09 at 07:00
-
3Microsoft's variant, _snprintf(), doesn't terminate the destination if the buffer isn't large enough: http://msdn.microsoft.com/en-us/library/2ts7cx93.aspx – Michael Burr Aug 13 '09 at 08:06
-
4Why would anyone worry about non-conformance in a nonstandard function with an underscore at the beginning of its name, when you could just wrap it with a function by the standard name and fix the lack-of-termination bug at the same time? – R.. GitHub STOP HELPING ICE Apr 11 '11 at 01:38
-
1I would vote this down if I could. It is absolutely false. If you choose to use the nonstandard, differently-named _snprintf, then its behavior may be different. However, this is not what the submitter asked. It looks like snprintf is not available on Windows; however, you can write your own without too much difficulty. – cmccabe Nov 05 '12 at 01:47