From d31c24f1e078e92cdb9c12ec0d27423f672cb2ab Mon Sep 17 00:00:00 2001 From: chrfranke Date: Thu, 22 Jan 2009 20:27:52 +0000 Subject: [PATCH] 2009-01-22 Christian Franke * kern/misc.c (grub_vsprintf): Fix size and termination of `format2' (precision) digit string. Allow `.format2' without `format1' (width). Limit input chars for `%s' output to `format2' if specified. This is compatible with standard printf (). --- ChangeLog | 7 +++++++ kern/misc.c | 50 +++++++++++++++++++++++++++++--------------------- 2 files changed, 36 insertions(+), 21 deletions(-) diff --git a/ChangeLog b/ChangeLog index bfec017f2..7c8a28345 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2009-01-22 Christian Franke + + * kern/misc.c (grub_vsprintf): Fix size and termination of `format2' + (precision) digit string. Allow `.format2' without `format1' (width). + Limit input chars for `%s' output to `format2' if specified. This is + compatible with standard printf (). + 2009-01-22 Christian Franke * disk/ata.c (grub_ata_wait_status): Replace by ... diff --git a/kern/misc.c b/kern/misc.c index 6fbc6510a..da64eb050 100644 --- a/kern/misc.c +++ b/kern/misc.c @@ -700,7 +700,7 @@ grub_vsprintf (char *str, const char *fmt, va_list args) char tmp[32]; char *p; unsigned int format1 = 0; - unsigned int format2 = 3; + unsigned int format2 = ~ 0U; char zerofill = ' '; int rightfill = 0; int n; @@ -727,20 +727,22 @@ grub_vsprintf (char *str, const char *fmt, va_list args) zerofill = '0'; format1 = grub_strtoul (s, 0, 10); fmt = p; - if (*p && *p == '.') + } + + if (*p && *p == '.') + { + p++; + fmt++; + while (*p && grub_isdigit (*p)) + p++; + + if (p > fmt) { - p++; - fmt++; - while (*p && grub_isdigit (*p)) - p++; - - if (p > fmt) - { - char fstr[p - fmt]; - grub_strncpy (fstr, fmt, p - fmt); - format2 = grub_strtoul (fstr, 0, 10); - fmt = p; - } + char fstr[p - fmt + 1]; + grub_strncpy (fstr, fmt, p - fmt); + fstr[p - fmt] = 0; + format2 = grub_strtoul (fstr, 0, 10); + fmt = p; } } @@ -847,13 +849,19 @@ grub_vsprintf (char *str, const char *fmt, va_list args) p = va_arg (args, char *); if (p) { - if (!rightfill && grub_strlen (p) < format1) - write_fill (zerofill, format1 - grub_strlen (p)); - - write_str (p); - - if (rightfill && grub_strlen (p) < format1) - write_fill (zerofill, format1 - grub_strlen (p)); + grub_size_t len = 0; + while (len < format2 && p[len]) + len++; + + if (!rightfill && len < format1) + write_fill (zerofill, format1 - len); + + grub_size_t i; + for (i = 0; i < len; i++) + write_char (*p++); + + if (rightfill && len < format1) + write_fill (zerofill, format1 - len); } else write_str ("(null)");