aboutsummaryrefslogtreecommitdiff
path: root/coreutils/dd.c
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2013-08-20 02:50:49 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2013-08-20 02:50:49 +0200
commit5b9910f0a4a1b7976c46e6f849aaa263180e5521 (patch)
tree4e5f1a63caa21286a01d5f6c2a3e585bcdf61ec9 /coreutils/dd.c
parente66a56de23fd08907f324d79e61ed2930ea5c350 (diff)
downloadbusybox-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.c31
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++;