git_parse_unsigned: reject negative values

git_parse_unsigned() relies on strtoumax() which unfortunately parses negative values as large positive integers. Fix this by rejecting any string that contains '-' as we do in strtoul_ui(). I've chosen to treat negative numbers as invalid input and set errno to EINVAL rather than ERANGE one the basis that they are never acceptable if we're looking for a unsigned integer. This is also consistent with the existing behavior of rejecting "1–2" with EINVAL. As we do not have unit tests for this function it is tested indirectly by checking that negative values of reject for core.bigFileThreshold are rejected. As this function is also used by OPT_MAGNITUDE() a test is added to check that rejects negative values too. Helped-by: Jeff King <peff@peff.net> Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk> Signed-off-by: Taylor Blau <me@ttaylorr.com>

Phillip Wood committed Nov 9, 2022 at 14:16 UTC 84356ff7709bd45c7e61632f1b837a7144a5178f
3 files changed +16
config.c
+5
@@ -1193,6 +1193,11 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
1193 uintmax_t val;
1194 uintmax_t factor;
1195
1196 + /* negative values would be accepted by strtoumax */
1197 + if (strchr(value, '-')) {
1198 + errno = EINVAL;
1199 + return 0;
1200 + }
1201 errno = 0;
1202 val = strtoumax(value, &end, 0);
1203 if (errno == ERANGE)
t/t0040-parse-options.sh
+5
@@ -709,4 +709,9 @@ test_expect_success 'subcommands are incompatible with KEEP_DASHDASH unless in c
709 grep ^BUG err
710 '
711
712 +test_expect_success 'negative magnitude' '
713 + test_must_fail test-tool parse-options --magnitude -1 >out 2>err &&
714 + grep "non-negative integer" err &&
715 + test_must_be_empty out
716 +'
717 test_done
t/t1050-large.sh
+6
@@ -5,6 +5,12 @@ test_description='adding and checking out large blobs'
5
6 . ./test-lib.sh
7
8 +test_expect_success 'core.bigFileThreshold must be non-negative' '
9 + test_must_fail git -c core.bigFileThreshold=-1 rev-parse >out 2>err &&
10 + grep "bad numeric config value" err &&
11 + test_must_be_empty out
12 +'
13 +
14 test_expect_success setup '
15 # clone does not allow us to pass core.bigfilethreshold to
16 # new repos, so set core.bigfilethreshold globally