diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2013-08-20 02:50:49 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2013-08-20 02:50:49 +0200 |
commit | 5b9910f0a4a1b7976c46e6f849aaa263180e5521 (patch) | |
tree | 4e5f1a63caa21286a01d5f6c2a3e585bcdf61ec9 /coreutils/dd.c | |
parent | e66a56de23fd08907f324d79e61ed2930ea5c350 (diff) | |
download | busybox-w32-5b9910f0a4a1b7976c46e6f849aaa263180e5521.tar.gz busybox-w32-5b9910f0a4a1b7976c46e6f849aaa263180e5521.tar.bz2 busybox-w32-5b9910f0a4a1b7976c46e6f849aaa263180e5521.zip |
dd: fail if swab is attempted on odd-sized block
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'coreutils/dd.c')
-rw-r--r-- | coreutils/dd.c | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/coreutils/dd.c b/coreutils/dd.c index d6aa5efb1..e22938859 100644 --- a/coreutils/dd.c +++ b/coreutils/dd.c | |||
@@ -151,13 +151,13 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
151 | enum { | 151 | enum { |
152 | /* Must be in the same order as OP_conv_XXX! */ | 152 | /* Must be in the same order as OP_conv_XXX! */ |
153 | /* (see "flags |= (1 << what)" below) */ | 153 | /* (see "flags |= (1 << what)" below) */ |
154 | FLAG_NOTRUNC = 1 << 0, | 154 | FLAG_NOTRUNC = (1 << 0) * ENABLE_FEATURE_DD_IBS_OBS, |
155 | FLAG_SYNC = 1 << 1, | 155 | FLAG_SYNC = (1 << 1) * ENABLE_FEATURE_DD_IBS_OBS, |
156 | FLAG_NOERROR = 1 << 2, | 156 | FLAG_NOERROR = (1 << 2) * ENABLE_FEATURE_DD_IBS_OBS, |
157 | FLAG_FSYNC = 1 << 3, | 157 | FLAG_FSYNC = (1 << 3) * ENABLE_FEATURE_DD_IBS_OBS, |
158 | FLAG_SWAB = 1 << 4, | 158 | FLAG_SWAB = (1 << 4) * ENABLE_FEATURE_DD_IBS_OBS, |
159 | /* end of conv flags */ | 159 | /* end of conv flags */ |
160 | FLAG_TWOBUFS = 1 << 5, | 160 | FLAG_TWOBUFS = (1 << 5) * ENABLE_FEATURE_DD_IBS_OBS, |
161 | FLAG_COUNT = 1 << 6, | 161 | FLAG_COUNT = 1 << 6, |
162 | }; | 162 | }; |
163 | static const char keywords[] ALIGN1 = | 163 | static const char keywords[] ALIGN1 = |
@@ -202,7 +202,7 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
202 | //swab swap every pair of input bytes: will abort on non-even reads | 202 | //swab swap every pair of input bytes: will abort on non-even reads |
203 | #endif | 203 | #endif |
204 | }; | 204 | }; |
205 | int exitcode = EXIT_FAILURE; | 205 | smallint exitcode = EXIT_FAILURE; |
206 | size_t ibs = 512, obs = 512; | 206 | size_t ibs = 512, obs = 512; |
207 | int i; | 207 | int i; |
208 | char *ibuf, *obuf; | 208 | char *ibuf, *obuf; |
@@ -210,12 +210,14 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
210 | struct { | 210 | struct { |
211 | int flags; | 211 | int flags; |
212 | size_t oc; | 212 | size_t oc; |
213 | ssize_t prev_read_size; /* for detecting swab failure */ | ||
213 | off_t count; | 214 | off_t count; |
214 | off_t seek, skip; | 215 | off_t seek, skip; |
215 | const char *infile, *outfile; | 216 | const char *infile, *outfile; |
216 | } Z; | 217 | } Z; |
217 | #define flags (Z.flags ) | 218 | #define flags (Z.flags ) |
218 | #define oc (Z.oc ) | 219 | #define oc (Z.oc ) |
220 | #define prev_read_size (Z.prev_read_size) | ||
219 | #define count (Z.count ) | 221 | #define count (Z.count ) |
220 | #define seek (Z.seek ) | 222 | #define seek (Z.seek ) |
221 | #define skip (Z.skip ) | 223 | #define skip (Z.skip ) |
@@ -381,14 +383,23 @@ int dd_main(int argc UNUSED_PARAM, char **argv) | |||
381 | n = 0; | 383 | n = 0; |
382 | } | 384 | } |
383 | if (flags & FLAG_SWAB) { | 385 | if (flags & FLAG_SWAB) { |
384 | /* If n is odd, last byte is not swapped: | 386 | uint16_t *p16, *end; |
387 | |||
388 | /* Our code allows only last read to be odd-sized */ | ||
389 | if (prev_read_size & 1) | ||
390 | bb_error_msg_and_die("can't swab %lu byte buffer", | ||
391 | (unsigned long)prev_read_size); | ||
392 | prev_read_size = n; | ||
393 | |||
394 | /* | ||
395 | * If n is odd, last byte is not swapped: | ||
385 | * echo -n "qwe" | dd conv=swab | 396 | * echo -n "qwe" | dd conv=swab |
386 | * prints "wqe". | 397 | * prints "wqe". |
387 | * The code does not handle correctly odd-sized reads | 398 | * The code does not handle correctly odd-sized reads |
388 | * in the *middle* of the input. FIXME. | 399 | * in the *middle* of the input. FIXME. |
389 | */ | 400 | */ |
390 | uint16_t *p16 = (void*) ibuf; | 401 | p16 = (void*) ibuf; |
391 | uint16_t *end = (void*) (ibuf + (n & ~(ssize_t)1)); | 402 | end = (void*) (ibuf + (n & ~(ssize_t)1)); |
392 | while (p16 < end) { | 403 | while (p16 < end) { |
393 | *p16 = bswap_16(*p16); | 404 | *p16 = bswap_16(*p16); |
394 | p16++; | 405 | p16++; |