summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko2016-08-26 20:14:31 +0200
committerDenys Vlasenko2016-08-26 20:14:31 +0200
commitd3d7f085ebf2898b62d4bb75566122c65be96454 (patch)
treeed989658fe8d3f16eb069738eac9c400a5147283
parentb6355e2bb5c931413735b7df2964e20e050bbc07 (diff)
downloadbusybox-d3d7f085ebf2898b62d4bb75566122c65be96454.zip
busybox-d3d7f085ebf2898b62d4bb75566122c65be96454.tar.gz
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.c51
1 files changed, 31 insertions, 20 deletions
diff --git a/libbb/dump.c b/libbb/dump.c
index 566881a..154be5d 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++;
}