From bf950cde6646dfbf4e7550184cde22d4b22185c4 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 4 Jul 2016 02:59:09 -0500 Subject: Fix a bug (octal digits are 0-7, not 0-8) and deal with a case where posix is explicitly outright insane (%b handles octal escapes differently for no obvious reason). --- tests/printf.test | 6 ++++++ toys/posix/printf.c | 11 +++++++---- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/tests/printf.test b/tests/printf.test index 7b077f0c..a3331748 100755 --- a/tests/printf.test +++ b/tests/printf.test @@ -59,3 +59,9 @@ testing "'%g %G' 78 79" "$PRINTF '%g %G' 78 79" "78 79" "" "" testing "'%s %s' 78 79" "$PRINTF '%s %s' 78 79" "78 79" "" "" testing "%.s acts like %.0s" "$PRINTF %.s_ 1 2 3 4 5" "_____" "" "" +testing "corner case" "$PRINTF '\\8'" '\8' '' '' + +# The posix spec explicitly specifies inconsistent behavior, +# so treating the \0066 in %b like the \0066 not in %b is wrong because posix. +testing "printf posix inconsistency" "$PRINTF '\\0066-%b' '\\0066'" "\x066-6" \ + "" "" diff --git a/toys/posix/printf.c b/toys/posix/printf.c index 365b8f36..2dd1e2f1 100644 --- a/toys/posix/printf.c +++ b/toys/posix/printf.c @@ -33,7 +33,7 @@ static int eat(char **s, char c) } // Parse escape sequences. -static int handle_slash(char **esc_val) +static int handle_slash(char **esc_val, int posix) { char *ptr = *esc_val; int len, base = 0; @@ -43,7 +43,10 @@ static int handle_slash(char **esc_val) // 0x12 hex escapes have 1-2 digits, \123 octal escapes have 1-3 digits. if (eat(&ptr, 'x')) base = 16; - else if (*ptr >= '0' && *ptr <= '8') base = 8; + else { + if (posix && *ptr=='0') ptr++; + if (*ptr >= '0' && *ptr <= '7') base = 8; + } len = (char []){0,3,2}[base/8]; // Not a hex or octal escape? (This catches trailing \) @@ -85,7 +88,7 @@ void printf_main(void) // Loop through characters in format while (*f) { - if (eat(&f, '\\')) putchar(handle_slash(&f)); + if (eat(&f, '\\')) putchar(handle_slash(&f, 0)); else if (!eat(&f, '%') || *f == '%') putchar(*f++); // Handle %escape @@ -110,7 +113,7 @@ void printf_main(void) // Output %esc using parsed format string if (c == 'b') { - while (*aa) putchar(eat(&aa, '\\') ? handle_slash(&aa) : *aa++); + while (*aa) putchar(eat(&aa, '\\') ? handle_slash(&aa, 1) : *aa++); continue; } else if (c == 'c') printf(toybuf, wp[0], wp[1], *aa); -- cgit v1.2.3