|Anonymous | Login||2018-12-15 23:45 UTC|
|Main | My View | View Issues | Change Log | Docs|
|Viewing Issue Simple Details|
|ID||Category||Severity||Type||Date Submitted||Last Update|
|0001173||[1003.1(2016)/Issue7+TC2] System Interfaces||Objection||Error||2017-11-29 18:24||2017-11-29 18:24|
|Final Accepted Text|
|Summary||0001173: scanf("%mc") contradiction|
The standard is clear that the conversion specifications for %s and %[ require the caller to supply an argument large enough for storing a terminating NUL, even though the terminating NUL is not part of the count of input bytes consumed if %n is used. Similarly, %ms and %m[ allocate enough memory to include a terminating NUL.
However, the standard has contradictory information on a terminating NUL when %c is in force. Line 32274 says %mc "shall cause a memory buffer to be allocated to hold the string converted including a terminating null character"; while line 32377 says "No null byte is added" without regards to whether m was in use.
The addition of the 'm' modifier in POSIX was modeled after the historical glibc behavior of "%as" (glibc has since followed POSIX' lead and now treats %a as parsing floating point, and prefers using %ms instead of %as for allocating a string). But glibc has NEVER written a trailing NUL byte for %mc (and never supported the older %ac, only %as). As such, this has the following consequences:
char *ptr = NULL;
if (scanf("%1ms%n", &ptr, &count) == 1 && count == 1)
assert(ptr == 0); // safe
if (scanf("%mc%n", &ptr, &count) == 1 && count == 1)
ptr; // undefined behavior; might be beyond the end of the malloc'd space, and even if in range, it does not have a defined value
The standard should be clear that the allocated buffer for 'm' does NOT have to include a trailing NUL byte for %c conversion, and that portable applications must not assume anything about the memory beyond the maximum field size or smaller %n count of input consumed in that situation. Alternatively, the standard could require that %mc allocates room for and writes a trailing NUL byte, although glibc would then need to be patched to be compliant.
At line 32272 (XSI scanf() DESCRIPTION), change the CX shaded text:
which shall cause a memory buffer to be allocated to hold the conversion results. If the specifier is %s or %[, the allocated buffer shall include space for a terminating null character.
|Tags||No tags attached.|
|There are no notes attached to this issue.|
|2017-11-29 18:24||eblake||New Issue|
|2017-11-29 18:24||eblake||Name||=> Eric Blake|
|2017-11-29 18:24||eblake||Organization||=> Red Hat|
|2017-11-29 18:24||eblake||User Reference||=> scanf|
|2017-11-29 18:24||eblake||Section||=> scanf|
|2017-11-29 18:24||eblake||Page Number||=> 950|
|2017-11-29 18:24||eblake||Line Number||=> 32272|
|2017-11-29 18:24||eblake||Interp Status||=> ---|
|Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group|