From f98bb2ddcbfed7033ae93ae8fe98b0540a9fb42f Mon Sep 17 00:00:00 2001 From: Delio Brignoli Date: Sat, 20 Aug 2016 10:51:28 +0200 Subject: [PATCH] py/mpprint: Fail an assertion with unsupported format specifiers. Arguments of an unknown type cannot be skipped and continuing to parse a format string after encountering an unknown format specifier leads to undefined behaviour. This patch helps to find use of unsupported formats. --- py/mpprint.c | 4 +++- tests/unix/extra_coverage.py.exp | 1 - unix/coverage.c | 2 -- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/py/mpprint.c b/py/mpprint.c index cb49b1227a..97ea33ad2a 100644 --- a/py/mpprint.c +++ b/py/mpprint.c @@ -537,10 +537,12 @@ int mp_vprintf(const mp_print_t *print, const char *fmt, va_list args) { chrs += mp_print_int(print, arg_value, *fmt == 'd', 10, 'a', flags, fill, width); break; } - // fall through to default case to print unknown format char + assert(!"unsupported fmt char"); } #endif default: + // if it's not %% then it's an unsupported format character + assert(*fmt == '%' || !"unsupported fmt char"); print->print_strn(print->data, fmt, 1); chrs += 1; break; diff --git a/tests/unix/extra_coverage.py.exp b/tests/unix/extra_coverage.py.exp index db282b152c..44749c45ea 100644 --- a/tests/unix/extra_coverage.py.exp +++ b/tests/unix/extra_coverage.py.exp @@ -7,7 +7,6 @@ ab abc false true (null) -t -2147483648 2147483648 80000000 diff --git a/unix/coverage.c b/unix/coverage.c index 9d53725543..ce1da50e2f 100644 --- a/unix/coverage.c +++ b/unix/coverage.c @@ -12,7 +12,6 @@ STATIC mp_obj_t extra_coverage(void) { // mp_printf (used by ports that don't have a native printf) { mp_printf(&mp_plat_print, "# mp_printf\n"); - mp_printf(&mp_plat_print, "%"); // nothing after percent mp_printf(&mp_plat_print, "%d %+d % d\n", -123, 123, 123); // sign mp_printf(&mp_plat_print, "%05d\n", -123); // negative number with zero padding mp_printf(&mp_plat_print, "%ld\n", 123); // long @@ -21,7 +20,6 @@ STATIC mp_obj_t extra_coverage(void) { mp_printf(&mp_plat_print, "%.*s\n", -1, "abc"); // negative string precision mp_printf(&mp_plat_print, "%b %b\n", 0, 1); // bools mp_printf(&mp_plat_print, "%s\n", NULL); // null string - mp_printf(&mp_plat_print, "%t\n"); // non-format char mp_printf(&mp_plat_print, "%d\n", 0x80000000); // should print signed mp_printf(&mp_plat_print, "%u\n", 0x80000000); // should print unsigned mp_printf(&mp_plat_print, "%x\n", 0x80000000); // should print unsigned