config: properly range-check integer values
[gitweb.git] / config.c
index e13a7b65e7615da7d788fddd001716a17baef5db..d3f71b261eb9c3e612c218bd58499ddd25513702 100644 (file)
--- a/config.c
+++ b/config.c
@@ -468,7 +468,7 @@ static int parse_unit_factor(const char *end, uintmax_t *val)
        return 0;
 }
 
-static int git_parse_long(const char *value, long *ret)
+static int git_parse_signed(const char *value, intmax_t *ret, intmax_t max)
 {
        if (value && *value) {
                char *end;
@@ -484,8 +484,7 @@ static int git_parse_long(const char *value, long *ret)
                        return 0;
                uval = abs(val);
                uval *= factor;
-               if ((uval > maximum_signed_value_of_type(long)) ||
-                   (abs(val) > uval))
+               if (uval > max || abs(val) > uval)
                        return 0;
                val *= factor;
                *ret = val;
@@ -494,7 +493,7 @@ static int git_parse_long(const char *value, long *ret)
        return 0;
 }
 
-int git_parse_ulong(const char *value, unsigned long *ret)
+int git_parse_unsigned(const char *value, uintmax_t *ret, uintmax_t max)
 {
        if (value && *value) {
                char *end;
@@ -508,8 +507,7 @@ int git_parse_ulong(const char *value, unsigned long *ret)
                oldval = val;
                if (!parse_unit_factor(end, &val))
                        return 0;
-               if ((val > maximum_unsigned_value_of_type(long)) ||
-                   (oldval > val))
+               if (val > max || oldval > val)
                        return 0;
                *ret = val;
                return 1;
@@ -517,6 +515,24 @@ int git_parse_ulong(const char *value, unsigned long *ret)
        return 0;
 }
 
+static int git_parse_int(const char *value, int *ret)
+{
+       intmax_t tmp;
+       if (!git_parse_signed(value, &tmp, maximum_signed_value_of_type(int)))
+               return 0;
+       *ret = tmp;
+       return 1;
+}
+
+int git_parse_ulong(const char *value, unsigned long *ret)
+{
+       uintmax_t tmp;
+       if (!git_parse_unsigned(value, &tmp, maximum_unsigned_value_of_type(long)))
+               return 0;
+       *ret = tmp;
+       return 1;
+}
+
 static void die_bad_config(const char *name)
 {
        if (cf && cf->name)
@@ -526,8 +542,8 @@ static void die_bad_config(const char *name)
 
 int git_config_int(const char *name, const char *value)
 {
-       long ret = 0;
-       if (!git_parse_long(value, &ret))
+       int ret;
+       if (!git_parse_int(value, &ret))
                die_bad_config(name);
        return ret;
 }
@@ -559,10 +575,10 @@ static int git_config_maybe_bool_text(const char *name, const char *value)
 
 int git_config_maybe_bool(const char *name, const char *value)
 {
-       long v = git_config_maybe_bool_text(name, value);
+       int v = git_config_maybe_bool_text(name, value);
        if (0 <= v)
                return v;
-       if (git_parse_long(value, &v))
+       if (git_parse_int(value, &v))
                return !!v;
        return -1;
 }