aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRob Landley <rob@landley.net>2016-07-04 02:59:09 -0500
committerRob Landley <rob@landley.net>2016-07-04 02:59:09 -0500
commitbf950cde6646dfbf4e7550184cde22d4b22185c4 (patch)
tree4edd49ed24eebda59352bc1daf8773bd961434e8
parent4e21ddd440f5d1381c96ae6465a12888dcb23446 (diff)
downloadtoybox-bf950cde6646dfbf4e7550184cde22d4b22185c4.tar.gz
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).
-rwxr-xr-xtests/printf.test6
-rw-r--r--toys/posix/printf.c11
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);