Q: How do I know the target buffer size required for any sprintf call? How can we avoid sprintf target buffer overflow?
A: There are no good answers to these two excellent questions (not yet. This may also be the biggest weakness of the traditional stdio library.
When the format string used for sprintf is known and relatively simple, the buffer size can sometimes be predicted. If the format string contains one or two % s, you can count the number of fixed characters (or calculated using sizeof) plus the return value of the strlen call to the inserted string. For integer types, the number of characters output by % d cannot exceed
(Sizeof (INT) * char_bit + 2)/3 + 1)/* + 1 '-'*/
Char_bit is defined in <limits. h>, but this computation may be too conservative. It calculates the number and stores the required bytes in octal. the same or fewer bytes can be used in decimal storage.
When the format string is more complex or unknown before running, it is as difficult to predict the buffer size as re-implementing sprintf, And it is prone to errors. There is a final line of defense technology, that is, using fprintf to output the same content to a memory area or temporary file, and then checking the return value of fprintf or the size of the temporary file, but please refer to question 19.13, beware of file writing errors.
If you cannot ensure that the buffer is large enough, you cannot call sprintf to avoid overwriting other memory zones after the buffer overflows. If the format string is known, use %. ns to control the length of % s extension, or use %. * s. See question 12.11.
To avoid overflow, you can use the sprintf version with a limited length, that is, snprintf. This method is used as follows:
Snprintf (BUF, bufsize, "you typed \" % s \ "", answer );
Snprintf has been provided in several stdio libraries for several years, including GNU and 4.4bsd. It has been standardized in c99.
Another benefit is that c99's snprintf provides a method to predict the buffer size required for any sprintf call. The snprintf of c99 returns the number of characters it may put in the buffer, and it can be called with a null pointer and a buffer size of 0. Therefore,
NCH = snprintf (null, 0, fmtstring,/* other arguments */);
This call can predict the number of characters required for format string extension.
Another (non-standard) option is the asprintf function, which is provided in both BSD and gnu c libraries. It calls malloc to allocate space for format strings and returns the pointer to the allocated memory zone. This method is used as follows:
Char * Buf;
Asprintf (& Buf, "% d = % s", 42, "forty-two ");
/* Now Buf points to malloc 'ed space containing formatted string */
From: <495 C language problems you must know>