Since -LONG_MIN results in LONG_MIN again, the operation itself is a signed integer overflow.
This can be observed with the following calls (best if compiled with -ftrapv or -fsanitize=undefined): $ numfmt --padding=-9223372036854775808 $ seq 1e-9223372036854775808 Technically, the change in seq "reduces" the precision, but a double or long double that small would be represented as 0 anyway. --- src/numfmt.c | 2 +- src/seq.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/numfmt.c b/src/numfmt.c index 8869791b0..8871a8c01 100644 --- a/src/numfmt.c +++ b/src/numfmt.c @@ -1496,7 +1496,7 @@ main (int argc, char **argv) case PADDING_OPTION: if (xstrtol (optarg, NULL, 10, &padding_width, "") != LONGINT_OK - || padding_width == 0) + || padding_width == 0 || padding_width < -LONG_MAX) die (EXIT_FAILURE, 0, _("invalid padding value %s"), quote (optarg)); if (padding_width < 0) diff --git a/src/seq.c b/src/seq.c index ddb63b642..2ca1e4f7b 100644 --- a/src/seq.c +++ b/src/seq.c @@ -197,7 +197,7 @@ scan_arg (const char *arg) e = strchr (arg, 'E'); if (e) { - long exponent = strtol (e + 1, NULL, 10); + long exponent = MAX (strtol (e + 1, NULL, 10), -LONG_MAX); ret.precision += exponent < 0 ? -exponent : - MIN (ret.precision, exponent); /* Don't account for e.... in the width since this is not output. */ -- 2.27.0