Inconsistent behavior with dd(1)
William Orr
will at worrbase.com
Fri Aug 15 06:02:24 UTC 2014
Hey,
I found some inconsistent behavior with dd(1) when it comes to specifying arguments in -CURRENT.
[ worr on terra ] ( ~ ) % dd if=/dev/zero of=/dev/null count=18446744073709551616
dd: count: Result too large
[ worr on terra ] ( ~ ) % dd if=/dev/zero of=/dev/null count=18446744073709551617
dd: count: Result too large
[ worr on terra ] ( ~ ) % dd if=/dev/zero of=/dev/null count=18446744073709551615
dd: count cannot be negative
[ worr on terra ] ( ~ ) % dd if=/dev/zero of=/dev/null count=-18446744073709551615
1+0 records in
1+0 records out
512 bytes transferred in 0.000373 secs (1373071 bytes/sec)
[ worr on terra ] ( ~ ) % dd if=/dev/zero of=/dev/null count=-1
dd: count cannot be negative
—
Any chance someone has the time and could take a look? https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=191263
Thanks,
William Orr
—
Here’s the patch:
Index: bin/dd/args.c
===================================================================
--- bin/dd/args.c (revision 267712)
+++ bin/dd/args.c (working copy)
@@ -186,46 +186,31 @@
static void
f_bs(char *arg)
{
- uintmax_t res;
-
- res = get_num(arg);
- if (res < 1 || res > SSIZE_MAX)
- errx(1, "bs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
- in.dbsz = out.dbsz = (size_t)res;
+ in.dbsz = out.dbsz = get_num(arg);
+ if (in.dbsz < 1 || out.dbsz < 1)
+ errx(1, "bs must be between 1 and %ju", (uintmax_t)-1);
}
static void
f_cbs(char *arg)
{
- uintmax_t res;
-
- res = get_num(arg);
- if (res < 1 || res > SSIZE_MAX)
- errx(1, "cbs must be between 1 and %jd", (intmax_t)SSIZE_MAX);
- cbsz = (size_t)res;
+ cbsz = get_num(arg);
+ if (cbsz < 1)
+ errx(1, "cbs must be between 1 and %ju", (uintmax_t)-1);
}
static void
f_count(char *arg)
{
- intmax_t res;
-
- res = (intmax_t)get_num(arg);
- if (res < 0)
- errx(1, "count cannot be negative");
- if (res == 0)
- cpy_cnt = (uintmax_t)-1;
- else
- cpy_cnt = (uintmax_t)res;
+ cpy_cnt = get_num(arg);
}
static void
f_files(char *arg)
{
-
files_cnt = get_num(arg);
if (files_cnt < 1)
- errx(1, "files must be between 1 and %jd", (uintmax_t)-1);
+ errx(1, "files must be between 1 and %ju", (uintmax_t)-1);
}
static void
@@ -241,14 +226,10 @@
static void
f_ibs(char *arg)
{
- uintmax_t res;
-
if (!(ddflags & C_BS)) {
- res = get_num(arg);
- if (res < 1 || res > SSIZE_MAX)
- errx(1, "ibs must be between 1 and %jd",
- (intmax_t)SSIZE_MAX);
- in.dbsz = (size_t)res;
+ in.dbsz = get_num(arg);
+ if (in.dbsz < 1)
+ errx(1, "ibs must be between 1 and %ju", (uintmax_t)-1);
}
}
@@ -262,14 +243,10 @@
static void
f_obs(char *arg)
{
- uintmax_t res;
-
if (!(ddflags & C_BS)) {
- res = get_num(arg);
- if (res < 1 || res > SSIZE_MAX)
- errx(1, "obs must be between 1 and %jd",
- (intmax_t)SSIZE_MAX);
- out.dbsz = (size_t)res;
+ out.dbsz = get_num(arg);
+ if (out.dbsz < 1)
+ errx(1, "obs must be between 1 and %ju", (uintmax_t)-1);
}
}
@@ -378,11 +355,14 @@
uintmax_t num, mult, prevnum;
char *expr;
+ if (val[0] == '-')
+ errx(1, "%s: cannot be negative", oper);
+
errno = 0;
num = strtouq(val, &expr, 0);
if (errno != 0) /* Overflow or underflow. */
err(1, "%s", oper);
-
+
if (expr == val) /* No valid digits. */
errx(1, "%s: illegal numeric value", oper);
Index: bin/dd/dd.c
===================================================================
--- bin/dd/dd.c (revision 267712)
+++ bin/dd/dd.c (working copy)
@@ -284,8 +284,6 @@
for (;;) {
switch (cpy_cnt) {
- case -1: /* count=0 was specified */
- return;
case 0:
break;
default:
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 801 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.freebsd.org/pipermail/freebsd-current/attachments/20140814/0a7c55f1/attachment.sig>
More information about the freebsd-current
mailing list