>From eaa31727a65a5ecb7f21b5036d9ad5a1c67d1286 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 15 Dec 2014 23:43:48 -0800 Subject: [PATCH] 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. --- src/dd.c | 37 +++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) diff --git a/src/dd.c b/src/dd.c index f830ef2..158f4db 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)); } } -- 1.9.3