diff options
author | Paul Eggert <eggert@cs.ucla.edu> | 2014-12-15 23:43:48 -0800 |
---|---|---|
committer | Paul Eggert <eggert@cs.ucla.edu> | 2014-12-15 23:44:17 -0800 |
commit | addae94b3bce48e79b0bf7021f5d8d17e313780b (patch) | |
tree | 1931df0b69e1b7c770182e354ae18c85583536a3 | |
parent | f57bfbb237ed11986af01e590acde49f52d49359 (diff) | |
download | coreutils-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.
-rw-r--r-- | src/dd.c | 37 |
1 files changed, 25 insertions, 12 deletions
@@ -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)); } } |