diff options
author | Denys Vlasenko | 2021-12-28 21:05:59 +0100 |
---|---|---|
committer | Denys Vlasenko | 2021-12-28 21:05:59 +0100 |
commit | 0fcc7f5f738e38766cde59ffd193643458c26cba (patch) | |
tree | 44ff1513fbd8e1a238c451dbc6c6b8f020e769c6 | |
parent | f1d06462e872270f38c497e36f8cd018ee7415bf (diff) | |
download | busybox-0fcc7f5f738e38766cde59ffd193643458c26cba.zip busybox-0fcc7f5f738e38766cde59ffd193643458c26cba.tar.gz |
scripts/echo.c: fix NUL handling in "abc\0 def"
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | scripts/echo.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/scripts/echo.c b/scripts/echo.c index 7474ccd..e3a07ad 100644 --- a/scripts/echo.c +++ b/scripts/echo.c @@ -153,25 +153,32 @@ int main(int argc, char **argv) if (!eflag) { /* optimization for very common case */ fputs(arg, stdout); - } else while ((c = *arg++)) { - if (c == eflag) { /* Check for escape seq. */ + } else + while ((c = *arg++) != '\0') { + if (c == eflag) { + /* This is an "\x" sequence */ + if (*arg == 'c') { - /* '\c' means cancel newline and + /* "\c" means cancel newline and * ignore all subsequent chars. */ goto ret; } - { - /* Since SUSv3 mandates a first digit of 0, 4-digit octals - * of the form \0### are accepted. */ - if (*arg == '0') { - /* NB: don't turn "...\0" into "...\" */ - if (arg[1] && ((unsigned char)(arg[1]) - '0') < 8) { - arg++; - } + /* Since SUSv3 mandates a first digit of 0, 4-digit octals + * of the form \0### are accepted. */ + if (*arg == '0') { + if ((unsigned char)(arg[1] - '0') < 8) { + /* 2nd char is 0..7: skip leading '0' */ + arg++; } - /* bb_process_escape_sequence handles NUL correctly - * ("...\" case. */ - c = bb_process_escape_sequence(&arg); + } + /* bb_process_escape_sequence handles NUL correctly + * ("...\" case). */ + { + /* optimization: don't force arg to be on-stack, + * use another variable for that. ~30 bytes win */ + const char *z = arg; + c = bb_process_escape_sequence(&z); + arg = z; } } putchar(c); |