aboutsummaryrefslogtreecommitdiff
path: root/coreutils/printf.c
diff options
context:
space:
mode:
Diffstat (limited to 'coreutils/printf.c')
-rw-r--r--coreutils/printf.c19
1 files changed, 17 insertions, 2 deletions
diff --git a/coreutils/printf.c b/coreutils/printf.c
index 1437951a8..3dd43a978 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -131,13 +131,28 @@ static double my_xstrtod(const char *arg)
return result;
}
+/* Handles %b */
static void print_esc_string(const char *str)
{
char c;
while ((c = *str) != '\0') {
str++;
- if (c == '\\')
- c = bb_process_escape_sequence(&str);
+ if (c == '\\') {
+ /* %b also accepts 4-digit octals of the form \0### */
+ if (*str == '0') {
+ if ((unsigned char)(str[1] - '0') < 8) {
+ /* 2nd char is 0..7: skip leading '0' */
+ str++;
+ }
+ }
+ {
+ /* optimization: don't force arg to be on-stack,
+ * use another variable for that. */
+ const char *z = str;
+ c = bb_process_escape_sequence(&z);
+ str = z;
+ }
+ }
putchar(c);
}
}