diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2021-10-08 23:03:54 +0200 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2021-10-08 23:03:54 +0200 |
| commit | 86ba007b84ae1ebe35e88c57e023caac3d2d9903 (patch) | |
| tree | 5e80e0d26c2cefec73ba7f2000adccca62641daf /util-linux | |
| parent | d315a77a79817d364a1562f4457c21fbb8174025 (diff) | |
| download | busybox-w32-86ba007b84ae1ebe35e88c57e023caac3d2d9903.tar.gz busybox-w32-86ba007b84ae1ebe35e88c57e023caac3d2d9903.tar.bz2 busybox-w32-86ba007b84ae1ebe35e88c57e023caac3d2d9903.zip | |
xxd: fix -p -r, closes 13881
function old new delta
xxd_main 893 890 -3
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'util-linux')
| -rw-r--r-- | util-linux/hexdump_xxd.c | 51 |
1 files changed, 38 insertions, 13 deletions
diff --git a/util-linux/hexdump_xxd.c b/util-linux/hexdump_xxd.c index fe78f6242..76dada983 100644 --- a/util-linux/hexdump_xxd.c +++ b/util-linux/hexdump_xxd.c | |||
| @@ -69,7 +69,7 @@ | |||
| 69 | #define OPT_c (1 << 7) | 69 | #define OPT_c (1 << 7) |
| 70 | #define OPT_o (1 << 8) | 70 | #define OPT_o (1 << 8) |
| 71 | 71 | ||
| 72 | static void reverse(unsigned opt, unsigned cols, const char *filename) | 72 | static void reverse(unsigned opt, const char *filename) |
| 73 | { | 73 | { |
| 74 | FILE *fp; | 74 | FILE *fp; |
| 75 | char *buf; | 75 | char *buf; |
| @@ -77,9 +77,9 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |||
| 77 | fp = filename ? xfopen_for_read(filename) : stdin; | 77 | fp = filename ? xfopen_for_read(filename) : stdin; |
| 78 | 78 | ||
| 79 | while ((buf = xmalloc_fgetline(fp)) != NULL) { | 79 | while ((buf = xmalloc_fgetline(fp)) != NULL) { |
| 80 | char *p = buf; | 80 | char *p; |
| 81 | unsigned cnt = cols; | ||
| 82 | 81 | ||
| 82 | p = buf; | ||
| 83 | if (!(opt & OPT_p)) { | 83 | if (!(opt & OPT_p)) { |
| 84 | /* skip address */ | 84 | /* skip address */ |
| 85 | while (isxdigit(*p)) p++; | 85 | while (isxdigit(*p)) p++; |
| @@ -92,9 +92,9 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |||
| 92 | } | 92 | } |
| 93 | 93 | ||
| 94 | /* Process hex bytes optionally separated by whitespace */ | 94 | /* Process hex bytes optionally separated by whitespace */ |
| 95 | do { | 95 | for (;;) { |
| 96 | uint8_t val, c; | 96 | uint8_t val, c; |
| 97 | 97 | nibble1: | |
| 98 | p = skip_whitespace(p); | 98 | p = skip_whitespace(p); |
| 99 | 99 | ||
| 100 | c = *p++; | 100 | c = *p++; |
| @@ -102,8 +102,19 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |||
| 102 | val = c - '0'; | 102 | val = c - '0'; |
| 103 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') | 103 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') |
| 104 | val = (c|0x20) - ('a' - 10); | 104 | val = (c|0x20) - ('a' - 10); |
| 105 | else | 105 | else { |
| 106 | /* xxd V1.10 is inconsistent here. | ||
| 107 | * echo -e "31 !3 0a 0a" | xxd -r -p | ||
| 108 | * is "10<a0>" (no <cr>) - "!" is ignored, | ||
| 109 | * but | ||
| 110 | * echo -e "31 !!343434\n30 0a" | xxd -r -p | ||
| 111 | * is "10<cr>" - "!!" drops rest of the line. | ||
| 112 | * We will ignore all invalid chars: | ||
| 113 | */ | ||
| 114 | if (c != '\0') | ||
| 115 | goto nibble1; | ||
| 106 | break; | 116 | break; |
| 117 | } | ||
| 107 | val <<= 4; | 118 | val <<= 4; |
| 108 | 119 | ||
| 109 | /* Works the same with xxd V1.10: | 120 | /* Works the same with xxd V1.10: |
| @@ -111,6 +122,7 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |||
| 111 | * echo "31 0 9 32 0a" | xxd -r -p | 122 | * echo "31 0 9 32 0a" | xxd -r -p |
| 112 | * thus allow whitespace even within the byte: | 123 | * thus allow whitespace even within the byte: |
| 113 | */ | 124 | */ |
| 125 | nibble2: | ||
| 114 | p = skip_whitespace(p); | 126 | p = skip_whitespace(p); |
| 115 | 127 | ||
| 116 | c = *p++; | 128 | c = *p++; |
| @@ -118,10 +130,23 @@ static void reverse(unsigned opt, unsigned cols, const char *filename) | |||
| 118 | val |= c - '0'; | 130 | val |= c - '0'; |
| 119 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') | 131 | else if ((c|0x20) >= 'a' && (c|0x20) <= 'f') |
| 120 | val |= (c|0x20) - ('a' - 10); | 132 | val |= (c|0x20) - ('a' - 10); |
| 121 | else | 133 | else { |
| 122 | break; | 134 | if (c != '\0') { |
| 135 | /* "...3<not_hex_char>..." ignores both chars */ | ||
| 136 | goto nibble1; | ||
| 137 | } | ||
| 138 | /* Nibbles can join even through newline: | ||
| 139 | * echo -e "31 3\n2 0a" | xxd -r -p | ||
| 140 | * is "12<cr>". | ||
| 141 | */ | ||
| 142 | free(buf); | ||
| 143 | p = buf = xmalloc_fgetline(fp); | ||
| 144 | if (!buf) | ||
| 145 | break; | ||
| 146 | goto nibble2; | ||
| 147 | } | ||
| 123 | putchar(val); | 148 | putchar(val); |
| 124 | } while (!(opt & OPT_p) || --cnt != 0); | 149 | } |
| 125 | free(buf); | 150 | free(buf); |
| 126 | } | 151 | } |
| 127 | //fclose(fp); | 152 | //fclose(fp); |
| @@ -174,6 +199,10 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
| 174 | //BUGGY for /proc/version (unseekable?) | 199 | //BUGGY for /proc/version (unseekable?) |
| 175 | } | 200 | } |
| 176 | 201 | ||
| 202 | if (opt & OPT_r) { | ||
| 203 | reverse(opt, argv[0]); | ||
| 204 | } | ||
| 205 | |||
| 177 | if (opt & OPT_o) { | 206 | if (opt & OPT_o) { |
| 178 | /* -o accepts negative numbers too */ | 207 | /* -o accepts negative numbers too */ |
| 179 | dumper->xxd_displayoff = xstrtoll(opt_o, /*base:*/ 0); | 208 | dumper->xxd_displayoff = xstrtoll(opt_o, /*base:*/ 0); |
| @@ -194,10 +223,6 @@ int xxd_main(int argc UNUSED_PARAM, char **argv) | |||
| 194 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " | 223 | bb_dump_add(dumper, "\"%08.8_ax: \""); // "address: " |
| 195 | } | 224 | } |
| 196 | 225 | ||
| 197 | if (opt & OPT_r) { | ||
| 198 | reverse(opt, cols, argv[0]); | ||
| 199 | } | ||
| 200 | |||
| 201 | if (bytes < 1 || bytes >= cols) { | 226 | if (bytes < 1 || bytes >= cols) { |
| 202 | sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "XX" | 227 | sprintf(buf, "%u/1 \"%%02x\"", cols); // cols * "XX" |
| 203 | bb_dump_add(dumper, buf); | 228 | bb_dump_add(dumper, buf); |
