diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-26 20:14:31 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-08-26 20:14:31 +0200 |
commit | d3d7f085ebf2898b62d4bb75566122c65be96454 (patch) | |
tree | ed989658fe8d3f16eb069738eac9c400a5147283 | |
parent | b6355e2bb5c931413735b7df2964e20e050bbc07 (diff) |
hexdump: fix numerous bugs in handling of backslashes
Was:
t=48\\ t=45\\ t=4c\\ t=4c\\ t=4f\\ t=0a\\
Now:
=48=\n =45=\n =4c=\n =4c=\n =4f=\n =0a=\n
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | libbb/dump.c | 51 |
1 files changed, 31 insertions, 20 deletions
diff --git a/libbb/dump.c b/libbb/dump.c index 566881a78..154be5d80 100644 --- a/libbb/dump.c +++ b/libbb/dump.c @@ -157,7 +157,7 @@ static NOINLINE void rewrite(priv_dumper_t *dumper, FS *fs) /* * figure out the byte count for each conversion; * rewrite the format as necessary, set up blank- - * pbb_dump_adding for end of data. + * padding for end of data. */ if (*p1 == 'c') { pr->flags = F_CHAR; @@ -466,14 +466,14 @@ static void bpad(PR *pr) } static const char conv_str[] ALIGN1 = - "\0\\0\0" - "\007\\a\0" /* \a */ - "\b\\b\0" - "\f\\b\0" - "\n\\n\0" - "\r\\r\0" - "\t\\t\0" - "\v\\v\0" + "\0" "\\""0""\0" + "\007""\\""a""\0" /* \a */ + "\b" "\\""b""\0" + "\f" "\\""f""\0" + "\n" "\\""n""\0" + "\r" "\\""r""\0" + "\t" "\\""t""\0" + "\v" "\\""v""\0" ; @@ -485,7 +485,7 @@ static void conv_c(PR *pr, unsigned char *p) do { if (*p == *str) { ++str; - goto strpr; + goto strpr; /* map e.g. '\n' to "\\n" */ } str += 4; } while (*str); @@ -702,8 +702,6 @@ int FAST_FUNC bb_dump_dump(dumper_t *pub_dumper, char **argv) void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) { const char *p; - char *p1; - char *p2; FS *tfs; FU *tfu, **nextfupp; const char *savep; @@ -779,29 +777,42 @@ void FAST_FUNC bb_dump_add(dumper_t* pub_dumper, const char *fmt) } } tfu->fmt = xstrndup(savep, p - savep); -/* escape(tfu->fmt); */ - - p1 = tfu->fmt; /* alphabetic escape sequences have to be done in place */ + strcpy_and_process_escape_sequences(tfu->fmt, tfu->fmt); + /* unknown mappings are not changed: "\z" -> '\\' 'z' */ + /* trailing backslash, if any, is preserved */ +#if 0 + char *p1; + char *p2; + p1 = tfu->fmt; for (p2 = p1;; ++p1, ++p2) { - if (*p1 == '\0') { - *p2 = *p1; + *p2 = *p1; + if (*p1 == '\0') break; - } + if (*p1 == '\\') { - const char *cs = conv_str + 4; - ++p1; + const char *cs; + + p1++; *p2 = *p1; + if (*p1 == '\0') { + /* "...\" trailing backslash. Eaten. */ + break; + } + cs = conv_str + 4; /* skip NUL element */ do { + /* map e.g. "\n" -> '\n' */ if (*p1 == cs[2]) { *p2 = cs[0]; break; } cs += 4; } while (*cs); + /* unknown mappings remove bkslash: "\z" -> 'z' */ } } +#endif p++; } |