Bug#208308: *printf() and incomplete multibyte sequences may cause infinite loops in applications
Package: libc6
Version: 2.3.2-4
Lets look at the following test program:
| #include <stdio.h>
| #include <stdarg.h>
| #include <locale.h>
| #include <wchar.h>
|
| void vmain (const char *fmt, ...)
| {
| va_list args;
| int rc;
|
| va_start (args, fmt);
| rc = vprintf (fmt, args);
| va_end (args);
| printf ("rc %d %d\n", rc, fwide (stdout));
| }
|
| int main()
| {
| const char *display = "\xe3\x83\x82x";
|
| setlocale (LC_ALL, "");
| vmain ("'%.*s'\n", 1, display);
| vmain ("'%.*s'\n", 3, display + 1);
| return 0;
| }
Now, in the C locale it functions properly:
| 'ã'
| rc 4 -1
| 'x'
| rc 6 -1
(the \x82 and \x83 are nonprintable, but hexdump -C reveals they are indeed
printed)
Now, in the en_US.UTF-8 locale, the output is broken:
| ''
| rc 3 -1
| 'rc -1 -1
The first case may be okay: the sequence is incomplete. However, in the
second case, the broken sequence is not only dropped, but parsing of the
format string is ceased alltogether - the trailing quote and newline is
missing as well! The bug is not only present in vprintf(), but also in
vsnprintf(), so you can't argue about byte-oriented vs. multibyte-oriented.
In fact, vsnprintf(buffer, sizeof(buffer), "%.*s", 3, "\x83\x82xyz") will
always return -1, no matter how large the buffer actually is. The sample
code given in the man page will turn into an infinite loop because of this!
Reply to: