OSDN Git Service

*printf: Violation of precision with null string
authorJones Desougi <jones.desougi@27m.se>
Thu, 10 Jun 2010 13:04:51 +0000 (15:04 +0200)
committerBernhard Reutner-Fischer <rep.dot.nop@gmail.com>
Wed, 9 Feb 2011 19:17:28 +0000 (20:17 +0100)
When a string format is processed and the argument is NULL, this yields
"(null)" regardless of precision. This does not make sense, precision
should not be exceeded. A simple test shows that glibc outputs nothing
if precision is smaller than six and the attached patch implements this
same behaviour.

Consider the not uncommon case of strings implemented like this:
struct string { int len; char *ptr; };
There is often no nultermination and they may be printed like this:
printf("%.*s", string.len, string.ptr);
If len is 0 then ptr may be anything, but NULL is a common value.
Obviously the empty string would be expected, not "(null)".

Signed-off-by: Jones Desougi <jones.desougi@27m.se>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
libc/stdio/_vfprintf.c

index 3b00708..fa5dc44 100644 (file)
@@ -1670,6 +1670,9 @@ static int _do_one_spec(FILE * __restrict stream,
 #endif
                                        s = "(null)";
                                        slen = 6;
+                                       /* Use an empty string rather than truncation if precision is too small. */
+                                       if (ppfs->info.prec >= 0 && ppfs->info.prec < slen)
+                                               slen = 0;
                                }
                        } else {                        /* char */
                                s = buf;
@@ -1726,6 +1729,9 @@ static int _do_one_spec(FILE * __restrict stream,
                                NULL_STRING:
                                        s = "(null)";
                                        SLEN = slen = 6;
+                                       /* Use an empty string rather than truncation if precision is too small. */
+                                       if (ppfs->info.prec >= 0 && ppfs->info.prec < slen)
+                                               SLEN = slen = 0;
                                }
                        } else {                        /* char */
                                *wbuf = btowc( (unsigned char)(*((const int *) *argptr)) );