]> git.scripts.mit.edu Git - git.git/commitdiff
config: set errno in numeric git_parse_* functions
authorJeff King <peff@peff.net>
Sun, 8 Sep 2013 08:36:42 +0000 (04:36 -0400)
committerJunio C Hamano <gitster@pobox.com>
Mon, 9 Sep 2013 18:06:38 +0000 (11:06 -0700)
When we are parsing an integer or unsigned long, we use
the strto*max functions, which properly set errno to ERANGE
if we get a large value. However, we also do further range
checks after applying our multiplication factor, but do not
set ERANGE. This means that a caller cannot tell if an error
was caused by ERANGE or if the input was simply not a valid
number.

This patch teaches git_parse_signed and git_parse_unsigned to set
ERANGE for range errors, and EINVAL for other errors, so that the
caller can reliably tell these cases apart.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
config.c

index d3f71b261eb9c3e612c218bd58499ddd25513702..9a42ad2ded7820b407247991dc3db4f326f44168 100644 (file)
--- a/config.c
+++ b/config.c
@@ -480,16 +480,21 @@ static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
                val = strtoimax(value, &end, 0);
                if (errno == ERANGE)
                        return 0;
-               if (!parse_unit_factor(end, &factor))
+               if (!parse_unit_factor(end, &factor)) {
+                       errno = EINVAL;
                        return 0;
+               }
                uval = abs(val);
                uval *= factor;
-               if (uval > max || abs(val) > uval)
+               if (uval > max || abs(val) > uval) {
+                       errno = ERANGE;
                        return 0;
+               }
                val *= factor;
                *ret = val;
                return 1;
        }
+       errno = EINVAL;
        return 0;
 }
 
@@ -505,13 +510,18 @@ int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
                if (errno == ERANGE)
                        return 0;
                oldval = val;
-               if (!parse_unit_factor(end, &val))
+               if (!parse_unit_factor(end, &val)) {
+                       errno = EINVAL;
                        return 0;
-               if (val > max || oldval > val)
+               }
+               if (val > max || oldval > val) {
+                       errno = ERANGE;
                        return 0;
+               }
                *ret = val;
                return 1;
        }
+       errno = EINVAL;
        return 0;
 }