diff --git a/ChangeLog b/ChangeLog index 5691d2919..e5606fd57 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2013-10-19 Vladimir Serbinenko + + * grub-core/kern/misc.c (grub_vsnprintf_real): Fix formatting of + "(null)" string. + Simplify expressions to save around 256 bytes in kernel.img. + * tests/printf_unit_test.c (printf_test): Add "(null)" tests. + 2013-10-19 Vladimir Serbinenko * grub-core/tests/video_checksum.c (grub_video_capture_write_bmp): diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c index c2a9163a3..fbf77c9a2 100644 --- a/grub-core/kern/misc.c +++ b/grub-core/kern/misc.c @@ -828,7 +828,6 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a while ((c = *fmt++) != 0) { char tmp[32]; - char *p; unsigned int format1 = 0; unsigned int format2 = ~ 0U; char zerofill = ' '; @@ -854,38 +853,20 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a fmt++; } - p = (char *) fmt; /* Read formatting parameters. */ - while (*p && grub_isdigit (*p)) - p++; - - if (p > fmt) + if (grub_isdigit (*fmt)) { - char s[p - fmt + 1]; - grub_strncpy (s, fmt, p - fmt); - s[p - fmt] = 0; - if (s[0] == '0') + if (fmt[0] == '0') zerofill = '0'; - format1 = grub_strtoul (s, 0, 10); - fmt = p; + format1 = grub_strtoul (fmt, (char **) &fmt, 10); } - if (*p && *p == '.') - { - p++; - fmt++; - while (*p && grub_isdigit (*p)) - p++; + if (*fmt == '.') + fmt++; + + if (grub_isdigit (*fmt)) + format2 = grub_strtoul (fmt, (char **) &fmt, 10); - if (p > fmt) - { - char fstr[p - fmt + 1]; - grub_strncpy (fstr, fmt, p - fmt); - fstr[p - fmt] = 0; - format2 = grub_strtoul (fstr, 0, 10); - fmt = p; - } - } if (*fmt == '$') { curn = format1 - 1; @@ -1003,25 +984,23 @@ grub_vsnprintf_real (char *str, grub_size_t max_len, const char *fmt0, va_list a break; case 's': - p = args[curn].p; - if (p) - { - grub_size_t len = 0; - while (len < format2 && p[len]) - len++; + { + grub_size_t len = 0; + const char *p = args[curn].p ? : "(null)"; - if (!rightfill && len < format1) - write_fill (zerofill, format1 - len); + while (len < format2 && p[len]) + len++; - grub_size_t i; - for (i = 0; i < len; i++) - write_char (*p++); + if (!rightfill && len < format1) + write_fill (zerofill, format1 - len); - if (rightfill && len < format1) - write_fill (zerofill, format1 - len); - } - else - write_str ("(null)"); + grub_size_t i; + for (i = 0; i < len; i++) + write_char (*p++); + + if (rightfill && len < format1) + write_fill (zerofill, format1 - len); + } break; diff --git a/tests/printf_unit_test.c b/tests/printf_unit_test.c index b88c88594..eb76bd002 100644 --- a/tests/printf_unit_test.c +++ b/tests/printf_unit_test.c @@ -28,6 +28,19 @@ printf_test (void) { char real[512]; char expected[512]; + char *null = NULL; + + grub_snprintf (real, sizeof (real), "%s", null); + snprintf (expected, sizeof (expected), "%s", null); + grub_test_assert (strcmp (real, expected) == 0, MSG); + + grub_snprintf (real, sizeof (real), "%10s", null); + snprintf (expected, sizeof (expected), "%10s", null); + grub_test_assert (strcmp (real, expected) == 0, MSG); + + grub_snprintf (real, sizeof (real), "%-10s", null); + snprintf (expected, sizeof (expected), "%-10s", null); + grub_test_assert (strcmp (real, expected) == 0, MSG); grub_snprintf (real, sizeof (real), "%d%%", 10); snprintf (expected, sizeof (expected), "%d%%", 10);