On Wed, Nov 09 2022, Phillip Wood via GitGitGadget wrote: > From: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> > > 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@xxxxxxxx> > Signed-off-by: Phillip Wood <phillip.wood@xxxxxxxxxxxxx> > --- > config.c | 5 +++++ > t/t0040-parse-options.sh | 5 +++++ > t/t1050-large.sh | 6 ++++++ > 3 files changed, 16 insertions(+) > > diff --git a/config.c b/config.c > index cbb5a3bab74..d5069d4f01d 100644 > --- a/config.c > +++ b/config.c > @@ -1193,6 +1193,11 @@ static int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max) > uintmax_t val; > uintmax_t factor; > > + /* negative values would be accepted by strtoumax */ > + if (strchr(value, '-')) { > + errno = EINVAL; > + return 0; > + } > errno = 0; > val = strtoumax(value, &end, 0); > if (errno == ERANGE) There's nothing wrong with this, but since the topic here is "some issues I noticed" here's another one: We don't actually care if you set "errno = EINVAL" here in particular, just as long as it's not "ERANGE", anything else will do. So, not worth a re-roll in itself, but maybe a prep patch (or follow-up) to do this would be nice? to make sure this errno handling is "reachable"? diff --git a/config.c b/config.c index ff4ea29784b..33d05fde0ea 100644 --- a/config.c +++ b/config.c @@ -1260,9 +1260,12 @@ NORETURN static void die_bad_number(const char *name, const char *value) { const char *error_type = (errno == ERANGE) ? - N_("out of range") : N_("invalid unit"); + N_("out of range") : errno == EINVAL ? N_("invalid unit") : NULL; const char *bad_numeric = N_("bad numeric config value '%s' for '%s': %s"); + if (!error_type) + BUG("unhandled errno %d: %s", errno, strerror(errno)); + if (!value) value = "";