[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

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: