summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2016-01-31 22:22:25 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2016-01-31 22:23:05 +0100
commit4a79224cfcde1c941f581d0c61edaf293e743af5 (patch)
tree6f10b991128b4f4c1a83bf61b33ebacfcb0ef802
parent2a4bba3ce2e00e55e6690fa8ba2607679277eed4 (diff)
printf: short-circuit output when argument to %b includes \c
printf wasn't correctly handling \c in an argument to the %b format specifier. printf %bXX OK\\c returned 'OK\cXX' rather than the expected 'OK'. function old new delta printf_main 886 899 +13 Signed-off-by: Ron Yorston <rmy@pobox.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--coreutils/printf.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 3dd43a978..9ee7350d0 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -131,8 +131,8 @@ static double my_xstrtod(const char *arg)
return result;
}
-/* Handles %b */
-static void print_esc_string(const char *str)
+/* Handles %b; return 1 if output is to be short-circuited by \c */
+static int print_esc_string(const char *str)
{
char c;
while ((c = *str) != '\0') {
@@ -145,6 +145,9 @@ static void print_esc_string(const char *str)
str++;
}
}
+ else if (*str == 'c') {
+ return 1;
+ }
{
/* optimization: don't force arg to be on-stack,
* use another variable for that. */
@@ -155,6 +158,8 @@ static void print_esc_string(const char *str)
}
putchar(c);
}
+
+ return 0;
}
static void print_direc(char *format, unsigned fmt_length,
@@ -280,7 +285,8 @@ static char **print_formatted(char *f, char **argv, int *conv_err)
}
if (*f == 'b') {
if (*argv) {
- print_esc_string(*argv);
+ if (print_esc_string(*argv))
+ return saved_argv; /* causes main() to exit */
++argv;
}
break;