diff options
-rwxr-xr-x | tests/echo.test | 7 | ||||
-rwxr-xr-x | tests/printf.test | 16 | ||||
-rw-r--r-- | toys/posix/echo.c | 12 | ||||
-rw-r--r-- | 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; |