From 81518f643d4d53b035b2cefbce25f06bd3cb5079 Mon Sep 17 00:00:00 2001 From: Elliott Hughes Date: Sat, 17 Aug 2019 19:53:56 -0700 Subject: echo/printf: expand test cases, fix \x corner cases. The behavior with "\xAV" (where the second hex digit is invalid) is different from the behavior with "\xVA", and echo and printf differ from each other. --- tests/echo.test | 7 +++++++ tests/printf.test | 16 ++++++++++++++++ toys/posix/echo.c | 12 +++++++++--- toys/posix/printf.c | 11 ++++------- 4 files changed, 36 insertions(+), 10 deletions(-) diff --git a/tests/echo.test b/tests/echo.test index 248454e7..80774e66 100755 --- a/tests/echo.test +++ b/tests/echo.test @@ -27,11 +27,18 @@ testcmd "-nex hello" "-nex hello" "-nex hello\n" "" "" testcmd "-e octal values" \ "-ne '\01234 \0060 \060 \0130\0131\0132 \077\012'" \ "S4 0 0 XYZ ?\n" "" "" +testcmd "-e invalid oct" "-ne 'one\\079two'" "one\a9two" "" "" +testcmd "-e \\0040" "-ne '\0040'" " " "" "" # Hexadecimal value tests testcmd "-e hexadecimal values" \ "-ne '\x534 \x30 \x58\x59\x5a \x3F\x0A'"\ "S4 0 XYZ ?\n" "" "" +testcmd "-e invalid hex 1" "-e 'one\xvdtwo'" "one\\xvdtwo\n" "" "" +testcmd "-e invalid hex 2" "-e 'one\xavtwo'" "one\nvtwo\n" "" "" + +# GNU extension for ESC +testcmd "-e \e" "-ne '\\e' | xxd -p" "1b\n" "" "" testcmd "-e \p" "-e '\\p'" "\\p\n" "" "" diff --git a/tests/printf.test b/tests/printf.test index eb0e0bec..a341615e 100755 --- a/tests/printf.test +++ b/tests/printf.test @@ -68,3 +68,19 @@ testing "printf posix inconsistency" "$PRINTF '\\0066-%b' '\\0066'" "\x066-6" \ testing "printf \x" "$PRINTF 'A\x1b\x2B\x3Q\xa' | od -An -tx1" \ " 41 1b 2b 03 51 0a\n" "" "" + +testing "printf \c" "$PRINTF 'one\ctwo'" "one" "" "" + +# An extra leading 0 is fine for %b, but not as a direct escape, for some +# reason... +testing "printf octal %b" "$PRINTF '\0007%b' '\0007' | xxd -p" "003707\n" "" "" + +# Unlike echo, printf errors out on bad hex. +testcmd "invalid hex 1" "'one\xvdtwo' 2>/dev/null || echo err" "oneerr\n" "" "" +testcmd "invalid hex 2" "'one\xavtwo'" "one\nvtwo" "" "" +# But bad octal is shown as text. +testcmd "invalid oct" "'one\079two'" "one\a9two" "" "" + +# extension for ESC +testcmd "%b \e" "'%b' '\\e' | xxd -p" "1b\n" "" "" +testcmd "\e" "'\\e' | xxd -p" "1b\n" "" "" diff --git a/toys/posix/echo.c b/toys/posix/echo.c index 94546ecd..70f4ce5e 100644 --- a/toys/posix/echo.c +++ b/toys/posix/echo.c @@ -51,7 +51,7 @@ void echo_main(void) // Should we output arg verbatim? - if (!(toys.optflags & FLAG_e)) { + if (!FLAG(e)) { xprintf("%s", arg); continue; } @@ -79,7 +79,13 @@ void echo_main(void) if (temp>='a' && temp<='f') { out = (out*16)+temp-'a'+10; c++; - } else break; + } else { + if (n==1) { + --c; + out = '\\'; + } + break; + } } } // Slash in front of unknown character, print literal. @@ -90,5 +96,5 @@ void echo_main(void) } // Output "\n" if no -n - if (!(toys.optflags&FLAG_n)) putchar('\n'); + if (!FLAG(n)) putchar('\n'); } diff --git a/toys/posix/printf.c b/toys/posix/printf.c index 5448d8c7..b51eddc0 100644 --- a/toys/posix/printf.c +++ b/toys/posix/printf.c @@ -9,12 +9,12 @@ USE_PRINTF(NEWTOY(printf, "<1?^", TOYFLAG_USR|TOYFLAG_BIN)) -config PRINTF +config PRINTF bool "printf" default y help usage: printf FORMAT [ARGUMENT...] - + Format and print ARGUMENT(s) according to FORMAT, using C printf syntax (% escapes for cdeEfgGiosuxX, \ escapes for abefnrtv0 or \OCTAL or \xHEX). */ @@ -61,11 +61,8 @@ static int handle_slash(char **esc_val, int posix) num = tolower(*ptr) - '0'; if (num >= 'a'-'0') num += '0'-'a'+10; if (num >= base) { - // Don't parse invalid hex value ala "\xvd", print it verbatim - if (base == 16 && len == 2) { - ptr--; - result = '\\'; - } + // "\xav" is "\xa"+"v", but "\xva" is an error. + if (base == 16 && len == 2) error_exit("bad \\x"); break; } result = (result*base)+num; -- cgit v1.2.3