dash built-in printf misbehaves on format specification %b
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
dash (Ubuntu) |
New
|
Undecided
|
Unassigned |
Bug Description
Ubuntu Release: 18.04 LTS
Package: dash_0.
Source: dash_0.
dash built-in printf does not handle correctly backslash-escape sequence expanding to a null byte while using the format specification "%b".
The manual page claims that for each \0num sequence it should output "an 8-bit character whose ASCII value is the 1-, 2-, or 3-digit octal number num". In practice, if the argument contains a sequence that expands to a null char, neither this char or the following ones are output.
As an example :
printf '%b' '\0000' outputs nothing (i.e. printf '%b' '\0000' | od -t x1 shows no bytes), while it should put a null byte.
printf '%b' '\0101\0000\0102' outputs A, but neither the null byte nor B.
coreutils printf, bash printf and ksh93 printf do put all the characters. I believe this is the POSIX behaviour for the '%b' specifier.
After a quick glance at the source, this seems to be due to the fact that arguments to '%b' are converted/expanded into a C-string, then printed using the printf(3) function with the '%s' format specifier. When an escape sequence expands to the null byte, this zero byte is written into the string, therefore terminating it (followings bytes are processed for conversion nevertheless).
In contrast, printing null bytes using the C-style octal escape sequence in the format string does work as expected, as these are output using putchar(3).
One might consider either keeping track of the real length of the converted C-string and handle it as a buffer rather than a null-terminated string, or printing character as they are being converted with putchar(3)