summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2014-12-15 23:43:48 -0800
committerPaul Eggert <eggert@cs.ucla.edu>2014-12-15 23:44:17 -0800
commitaddae94b3bce48e79b0bf7021f5d8d17e313780b (patch)
tree1931df0b69e1b7c770182e354ae18c85583536a3 /src
parentf57bfbb237ed11986af01e590acde49f52d49359 (diff)
downloadcoreutils-addae94b3bce48e79b0bf7021f5d8d17e313780b.tar.xz
dd: diagnose too-large numbers better
Reported by Isabella Parakiss in: http://lists.gnu.org/archive/html/bug-gnulib/2014-12/msg00184.html * src/dd.c (parse_integer): Return strtol_error code, not bool. All callers changed. (scanargs): Improve quality of diagnostic when a number is too large.
Diffstat (limited to 'src')
-rw-r--r--src/dd.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/src/dd.c b/src/dd.c
index f830ef2df..158f4dbd4 100644
--- a/src/dd.c
+++ b/src/dd.c
@@ -1307,14 +1307,15 @@ parse_symbols (char const *str, struct symbol_value const *table,
/* Return the value of STR, interpreted as a non-negative decimal integer,
optionally multiplied by various values.
- Set *INVALID if STR does not represent a number in this format. */
+ Set *INVALID to a nonzero error value if STR does not represent a
+ number in this format. */
static uintmax_t
-parse_integer (const char *str, bool *invalid)
+parse_integer (const char *str, strtol_error *invalid)
{
uintmax_t n;
char *suffix;
- enum strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");
+ strtol_error e = xstrtoumax (str, &suffix, 10, &n, "bcEGkKMPTwYZ0");
if (e == LONGINT_INVALID_SUFFIX_CHAR && *suffix == 'x')
{
@@ -1322,7 +1323,7 @@ parse_integer (const char *str, bool *invalid)
if (multiplier != 0 && n * multiplier / multiplier != n)
{
- *invalid = true;
+ *invalid = LONGINT_OVERFLOW;
return 0;
}
@@ -1330,7 +1331,7 @@ parse_integer (const char *str, bool *invalid)
}
else if (e != LONGINT_OK)
{
- *invalid = true;
+ *invalid = e;
return 0;
}
@@ -1384,27 +1385,33 @@ scanargs (int argc, char *const *argv)
N_("invalid status level"));
else
{
- bool invalid = false;
+ strtol_error invalid = LONGINT_OK;
uintmax_t n = parse_integer (val, &invalid);
+ uintmax_t n_min = 0;
+ uintmax_t n_max = UINTMAX_MAX;
if (operand_is (name, "ibs"))
{
- invalid |= ! (0 < n && n <= MAX_BLOCKSIZE (INPUT_BLOCK_SLOP));
+ n_min = 1;
+ n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);
input_blocksize = n;
}
else if (operand_is (name, "obs"))
{
- invalid |= ! (0 < n && n <= MAX_BLOCKSIZE (OUTPUT_BLOCK_SLOP));
+ n_min = 1;
+ n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);
output_blocksize = n;
}
else if (operand_is (name, "bs"))
{
- invalid |= ! (0 < n && n <= MAX_BLOCKSIZE (INPUT_BLOCK_SLOP));
+ n_min = 1;
+ n_max = MAX_BLOCKSIZE (INPUT_BLOCK_SLOP);
blocksize = n;
}
else if (operand_is (name, "cbs"))
{
- invalid |= ! (0 < n && n <= SIZE_MAX);
+ n_min = 1;
+ n_max = SIZE_MAX;
conversion_blocksize = n;
}
else if (operand_is (name, "skip"))
@@ -1419,8 +1426,14 @@ scanargs (int argc, char *const *argv)
usage (EXIT_FAILURE);
}
- if (invalid)
- error (EXIT_FAILURE, 0, _("invalid number %s"), quote (val));
+ if (n < n_min)
+ invalid = LONGINT_INVALID;
+ else if (n_max < n)
+ invalid = LONGINT_OVERFLOW;
+
+ if (invalid != LONGINT_OK)
+ error (EXIT_FAILURE, invalid == LONGINT_OVERFLOW ? EOVERFLOW : 0,
+ _("invalid number %s"), quote (val));
}
}