summaryrefslogtreecommitdiff
path: root/src/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util.c')
-rw-r--r--src/util.c38
1 files changed, 20 insertions, 18 deletions
diff --git a/src/util.c b/src/util.c
index 79b362f7f..20c88a1d3 100644
--- a/src/util.c
+++ b/src/util.c
@@ -68,12 +68,6 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
return 0;
}
-int git__strtol64(int64_t *result, const char *nptr, const char **endptr, int base)
-{
-
- return git__strntol64(result, nptr, (size_t)-1, endptr, base);
-}
-
int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base)
{
const char *p;
@@ -132,10 +126,20 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
v = c - 'A' + 10;
if (v >= base)
break;
- nn = n * base + (neg ? -v : v);
- if ((!neg && nn < n) || (neg && nn > n))
+ v = neg ? -v : v;
+ if (n > INT64_MAX / base || n < INT64_MIN / base) {
ovfl = 1;
- n = nn;
+ /* Keep on iterating until the end of this number */
+ continue;
+ }
+ nn = n * base;
+ if ((v > 0 && nn > INT64_MAX - v) ||
+ (v < 0 && nn < INT64_MIN - v)) {
+ ovfl = 1;
+ /* Keep on iterating until the end of this number */
+ continue;
+ }
+ n = nn + v;
}
Return:
@@ -156,28 +160,26 @@ Return:
return 0;
}
-int git__strtol32(int32_t *result, const char *nptr, const char **endptr, int base)
-{
-
- return git__strntol32(result, nptr, (size_t)-1, endptr, base);
-}
-
int git__strntol32(int32_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base)
{
- int error;
+ const char *tmp_endptr;
int32_t tmp_int;
int64_t tmp_long;
+ int error;
- if ((error = git__strntol64(&tmp_long, nptr, nptr_len, endptr, base)) < 0)
+ if ((error = git__strntol64(&tmp_long, nptr, nptr_len, &tmp_endptr, base)) < 0)
return error;
tmp_int = tmp_long & 0xFFFFFFFF;
if (tmp_int != tmp_long) {
- giterr_set(GITERR_INVALID, "failed to convert: '%s' is too large", nptr);
+ int len = tmp_endptr - nptr;
+ giterr_set(GITERR_INVALID, "failed to convert: '%.*s' is too large", len, nptr);
return -1;
}
*result = tmp_int;
+ if (endptr)
+ *endptr = tmp_endptr;
return error;
}