Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Portablilty of using percison when printf-ing non 0 terminated strings

As multiple questions on here also point out, you can printf a nonterminated string by formatting with a precision as maximum length to print. Something like

printf("%.*s\n", length, str);

will print length chars starting at str (or until the first 0 byte).

As pointed out here by jonathan-leffler, this is specified by posix here. And when reading the doc I discovered it actually never states this should work (or I couldn't find it) , as "The ‘%s’ conversion prints a string." and "A string is a null-terminated array of bytes [...] ". The regard about the precision states "A precision can be specified to indicate the maximum number of characters to write;".

My interpretation would be that the line above is actually undefined behavior, but because printf's implementation is efficient it doesn't read more than it writes.

So my question is: Is this interpretation correct and

TLDR: Should I stop using this printf trick when trying to be posix compliant as there exists an implementation where this might cause a buffer-overrun?

like image 302
Poohl Avatar asked Mar 17 '21 18:03

Poohl


People also ask

Does printf print until null terminator?

The printf function starts at the first char of the array and continues printing chars until it sees the null character. The null character is not printed.


1 Answers

What you're reading isn't the actual POSIX spec, but the GNU libc manual, which tends to be a little less precise for the sake of readability. The actual spec can be found at https://pubs.opengroup.org/onlinepubs/9699919799/functions/printf.html (it's even linked from Jonathan Leffler's answer which you link to), and it makes it clear that your code is fine:

s The argument shall be a pointer to an array of char. Bytes from the array shall be written up to (but not including) any terminating null byte. If the precision is specified, no more than that many bytes shall be written. If the precision is not specified or is greater than the size of the array, the application shall ensure that the array contains a null byte.

Note that they are careful not to use the word "string" for exactly the reason you point out.

The ISO C17 standard uses almost identical language, so your code is even portable to non-POSIX standard C implementations. (POSIX generally incorporates ISO C and many parts of the POSIX spec are copy/pasted from the C standard.)

like image 121
Nate Eldredge Avatar answered Oct 19 '22 02:10

Nate Eldredge