aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xtests/echo.test7
-rwxr-xr-xtests/printf.test16
-rw-r--r--toys/posix/echo.c12
-rw-r--r--toys/posix/printf.c11
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;