Unverified Commit bea65980 by Patrick Steinhardt Committed by GitHub

Merge pull request #4851 from pks-t/pks/strtol-removal

strtol removal
parents 11945461 ea19efc1
...@@ -171,7 +171,9 @@ static int commit_quick_parse( ...@@ -171,7 +171,9 @@ static int commit_quick_parse(
buffer--; buffer--;
} }
if ((buffer == committer_start) || (git__strtol64(&commit_time, (char *)(buffer + 1), NULL, 10) < 0)) if ((buffer == committer_start) ||
(git__strntol64(&commit_time, (char *)(buffer + 1),
buffer_end - buffer + 1, NULL, 10) < 0))
return commit_error(commit, "cannot parse commit time"); return commit_error(commit, "cannot parse commit time");
commit->time = commit_time; commit->time = commit_time;
......
...@@ -1300,7 +1300,7 @@ int git_config_parse_int64(int64_t *out, const char *value) ...@@ -1300,7 +1300,7 @@ int git_config_parse_int64(int64_t *out, const char *value)
const char *num_end; const char *num_end;
int64_t num; int64_t num;
if (!value || git__strtol64(&num, value, &num_end, 0) < 0) if (!value || git__strntol64(&num, value, strlen(value), &num_end, 0) < 0)
goto fail_parse; goto fail_parse;
switch (*num_end) { switch (*num_end) {
......
...@@ -2243,7 +2243,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size) ...@@ -2243,7 +2243,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size)
for (i = 0; i < 3; i++) { for (i = 0; i < 3; i++) {
int64_t tmp; int64_t tmp;
if (git__strtol64(&tmp, buffer, &endptr, 8) < 0 || if (git__strntol64(&tmp, buffer, size, &endptr, 8) < 0 ||
!endptr || endptr == buffer || *endptr || !endptr || endptr == buffer || *endptr ||
tmp < 0 || tmp > UINT32_MAX) { tmp < 0 || tmp > UINT32_MAX) {
index_entry_reuc_free(lost); index_entry_reuc_free(lost);
......
...@@ -152,7 +152,7 @@ GIT_INLINE(int) rebase_readint( ...@@ -152,7 +152,7 @@ GIT_INLINE(int) rebase_readint(
if ((error = rebase_readfile(asc_out, state_path, filename)) < 0) if ((error = rebase_readfile(asc_out, state_path, filename)) < 0)
return error; return error;
if (git__strtol32(&num, asc_out->ptr, &eol, 10) < 0 || num < 0 || *eol) { if (git__strntol32(&num, asc_out->ptr, asc_out->size, &eol, 10) < 0 || num < 0 || *eol) {
giterr_set(GITERR_REBASE, "the file '%s' contains an invalid numeric value", filename); giterr_set(GITERR_REBASE, "the file '%s' contains an invalid numeric value", filename);
return -1; return -1;
} }
......
...@@ -128,7 +128,8 @@ static int try_parse_numeric(int *n, const char *curly_braces_content) ...@@ -128,7 +128,8 @@ static int try_parse_numeric(int *n, const char *curly_braces_content)
int32_t content; int32_t content;
const char *end_ptr; const char *end_ptr;
if (git__strtol32(&content, curly_braces_content, &end_ptr, 10) < 0) if (git__strntol32(&content, curly_braces_content, strlen(curly_braces_content),
&end_ptr, 10) < 0)
return -1; return -1;
if (*end_ptr != '\0') if (*end_ptr != '\0')
...@@ -578,7 +579,7 @@ static int extract_how_many(int *n, const char *spec, size_t *pos) ...@@ -578,7 +579,7 @@ static int extract_how_many(int *n, const char *spec, size_t *pos)
} while (spec[(*pos)] == kind && kind == '~'); } while (spec[(*pos)] == kind && kind == '~');
if (git__isdigit(spec[*pos])) { if (git__isdigit(spec[*pos])) {
if (git__strtol32(&parsed, spec + *pos, &end_ptr, 10) < 0) if (git__strntol32(&parsed, spec + *pos, strlen(spec + *pos), &end_ptr, 10) < 0)
return GIT_EINVALIDSPEC; return GIT_EINVALIDSPEC;
accumulated += (parsed - 1); accumulated += (parsed - 1);
......
...@@ -231,7 +231,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, ...@@ -231,7 +231,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
const char *time_start = email_end + 2; const char *time_start = email_end + 2;
const char *time_end; const char *time_end;
if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0) { if (git__strntol64(&sig->when.time, time_start,
buffer_end - time_start, &time_end, 10) < 0) {
git__free(sig->name); git__free(sig->name);
git__free(sig->email); git__free(sig->email);
sig->name = sig->email = NULL; sig->name = sig->email = NULL;
...@@ -246,7 +247,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, ...@@ -246,7 +247,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
tz_start = time_end + 1; tz_start = time_end + 1;
if ((tz_start[0] != '-' && tz_start[0] != '+') || if ((tz_start[0] != '-' && tz_start[0] != '+') ||
git__strtol32(&offset, tz_start + 1, &tz_end, 10) < 0) { git__strntol32(&offset, tz_start + 1,
buffer_end - tz_start + 1, &tz_end, 10) < 0) {
/* malformed timezone, just assume it's zero */ /* malformed timezone, just assume it's zero */
offset = 0; offset = 0;
} }
......
...@@ -330,7 +330,7 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port) ...@@ -330,7 +330,7 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port)
return -1; return -1;
} }
if ((error = git__strtol32(&iport, port, NULL, 10)) < 0) { if ((error = git__strntol32(&iport, port, strlen(port), NULL, 10)) < 0) {
git__free(st); git__free(st);
return error; return error;
} }
......
...@@ -391,7 +391,7 @@ static int parse_len(size_t *out, const char *line, size_t linelen) ...@@ -391,7 +391,7 @@ static int parse_len(size_t *out, const char *line, size_t linelen)
} }
} }
if ((error = git__strtol32(&len, num, &num_end, 16)) < 0) if ((error = git__strntol32(&len, num, PKT_LEN_SIZE, &num_end, 16)) < 0)
return error; return error;
if (len < 0) if (len < 0)
......
...@@ -766,7 +766,8 @@ static int winhttp_connect( ...@@ -766,7 +766,8 @@ static int winhttp_connect(
t->connection = NULL; t->connection = NULL;
/* Prepare port */ /* Prepare port */
if (git__strtol32(&port, t->connection_data.port, NULL, 10) < 0) if (git__strntol32(&port, t->connection_data.port,
strlen(t->connection_data.port), NULL, 10) < 0)
return -1; return -1;
/* Prepare host */ /* Prepare host */
......
...@@ -91,7 +91,7 @@ static int read_tree_internal(git_tree_cache **out, ...@@ -91,7 +91,7 @@ static int read_tree_internal(git_tree_cache **out,
return -1; return -1;
/* Blank-terminated ASCII decimal number of entries in this tree */ /* Blank-terminated ASCII decimal number of entries in this tree */
if (git__strtol32(&count, buffer, &buffer, 10) < 0) if (git__strntol32(&count, buffer, buffer_end - buffer, &buffer, 10) < 0)
goto corrupted; goto corrupted;
tree->entry_count = count; tree->entry_count = count;
...@@ -100,7 +100,7 @@ static int read_tree_internal(git_tree_cache **out, ...@@ -100,7 +100,7 @@ static int read_tree_internal(git_tree_cache **out,
goto corrupted; goto corrupted;
/* Number of children of the tree, newline-terminated */ /* Number of children of the tree, newline-terminated */
if (git__strtol32(&count, buffer, &buffer, 10) < 0 || count < 0) if (git__strntol32(&count, buffer, buffer_end - buffer, &buffer, 10) < 0 || count < 0)
goto corrupted; goto corrupted;
tree->children_count = count; tree->children_count = count;
......
...@@ -68,12 +68,6 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src) ...@@ -68,12 +68,6 @@ int git_strarray_copy(git_strarray *tgt, const git_strarray *src)
return 0; 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) int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const char **endptr, int base)
{ {
const char *p; const char *p;
...@@ -132,10 +126,20 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha ...@@ -132,10 +126,20 @@ int git__strntol64(int64_t *result, const char *nptr, size_t nptr_len, const cha
v = c - 'A' + 10; v = c - 'A' + 10;
if (v >= base) if (v >= base)
break; break;
nn = n * base + (neg ? -v : v); v = neg ? -v : v;
if ((!neg && nn < n) || (neg && nn > n)) if (n > INT64_MAX / base || n < INT64_MIN / base) {
ovfl = 1; 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: Return:
...@@ -156,28 +160,26 @@ Return: ...@@ -156,28 +160,26 @@ Return:
return 0; 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 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; int32_t tmp_int;
int64_t tmp_long; 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; return error;
tmp_int = tmp_long & 0xFFFFFFFF; tmp_int = tmp_long & 0xFFFFFFFF;
if (tmp_int != tmp_long) { 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; return -1;
} }
*result = tmp_int; *result = tmp_int;
if (endptr)
*endptr = tmp_endptr;
return error; return error;
} }
......
...@@ -58,9 +58,7 @@ GIT_INLINE(int) git__signum(int val) ...@@ -58,9 +58,7 @@ GIT_INLINE(int) git__signum(int val)
return ((val > 0) - (val < 0)); return ((val > 0) - (val < 0));
} }
extern int git__strtol32(int32_t *n, const char *buff, const char **end_buf, int base);
extern int git__strntol32(int32_t *n, const char *buff, size_t buff_len, const char **end_buf, int base); extern int git__strntol32(int32_t *n, const char *buff, size_t buff_len, const char **end_buf, int base);
extern int git__strtol64(int64_t *n, const char *buff, const char **end_buf, int base);
extern int git__strntol64(int64_t *n, const char *buff, size_t buff_len, const char **end_buf, int base); extern int git__strntol64(int64_t *n, const char *buff, size_t buff_len, const char **end_buf, int base);
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
void test_core_strtol__int32(void) static void assert_l32_parses(const char *string, int32_t expected, int base)
{ {
int32_t i; int32_t i;
cl_git_pass(git__strntol32(&i, string, strlen(string), NULL, base));
cl_assert_equal_i(i, expected);
}
cl_git_pass(git__strtol32(&i, "123", NULL, 10)); static void assert_l32_fails(const char *string, int base)
cl_assert(i == 123); {
cl_git_pass(git__strtol32(&i, " +123 ", NULL, 10)); int32_t i;
cl_assert(i == 123); cl_git_fail(git__strntol32(&i, string, strlen(string), NULL, base));
cl_git_pass(git__strtol32(&i, " +2147483647 ", NULL, 10)); }
cl_assert(i == 2147483647);
cl_git_pass(git__strtol32(&i, " -2147483648 ", NULL, 10));
cl_assert(i == -2147483648LL);
cl_git_fail(git__strtol32(&i, " 2147483657 ", NULL, 10)); static void assert_l64_parses(const char *string, int64_t expected, int base)
cl_git_fail(git__strtol32(&i, " -2147483657 ", NULL, 10)); {
int64_t i;
cl_git_pass(git__strntol64(&i, string, strlen(string), NULL, base));
cl_assert_equal_i(i, expected);
} }
void test_core_strtol__int64(void) static void assert_l64_fails(const char *string, int base)
{ {
int64_t i; int64_t i;
cl_git_fail(git__strntol64(&i, string, strlen(string), NULL, base));
}
void test_core_strtol__int32(void)
{
assert_l32_parses("123", 123, 10);
assert_l32_parses(" +123 ", 123, 10);
assert_l32_parses(" +2147483647 ", 2147483647, 10);
assert_l32_parses(" -2147483648 ", -2147483648LL, 10);
assert_l32_parses("A", 10, 16);
assert_l32_parses("1x1", 1, 10);
cl_git_pass(git__strtol64(&i, "123", NULL, 10)); assert_l32_fails("", 10);
cl_assert(i == 123); assert_l32_fails("a", 10);
cl_git_pass(git__strtol64(&i, " +123 ", NULL, 10)); assert_l32_fails("x10x", 10);
cl_assert(i == 123); assert_l32_fails(" 2147483657 ", 10);
cl_git_pass(git__strtol64(&i, " +2147483647 ", NULL, 10)); assert_l32_fails(" -2147483657 ", 10);
cl_assert(i == 2147483647);
cl_git_pass(git__strtol64(&i, " -2147483648 ", NULL, 10));
cl_assert(i == -2147483648LL);
cl_git_pass(git__strtol64(&i, " 2147483657 ", NULL, 10));
cl_assert(i == 2147483657LL);
cl_git_pass(git__strtol64(&i, " -2147483657 ", NULL, 10));
cl_assert(i == -2147483657LL);
cl_git_pass(git__strtol64(&i, " 9223372036854775807 ", NULL, 10));
cl_assert(i == INT64_MAX);
cl_git_pass(git__strtol64(&i, " -9223372036854775808 ", NULL, 10));
cl_assert(i == INT64_MIN);
cl_git_pass(git__strtol64(&i, " 0x7fffffffffffffff ", NULL, 16));
cl_assert(i == INT64_MAX);
cl_git_pass(git__strtol64(&i, " -0x8000000000000000 ", NULL, 16));
cl_assert(i == INT64_MIN);
} }
void test_core_strtol__int64(void)
{
assert_l64_parses("123", 123, 10);
assert_l64_parses(" +123 ", 123, 10);
assert_l64_parses(" +2147483647 ", 2147483647, 10);
assert_l64_parses(" -2147483648 ", -2147483648LL, 10);
assert_l64_parses(" 2147483657 ", 2147483657LL, 10);
assert_l64_parses(" -2147483657 ", -2147483657LL, 10);
assert_l64_parses(" 9223372036854775807 ", INT64_MAX, 10);
assert_l64_parses(" -9223372036854775808 ", INT64_MIN, 10);
assert_l64_parses(" 0x7fffffffffffffff ", INT64_MAX, 16);
assert_l64_parses(" -0x8000000000000000 ", INT64_MIN, 16);
assert_l64_parses("1a", 26, 16);
assert_l64_parses("1A", 26, 16);
assert_l64_fails("", 10);
assert_l64_fails("a", 10);
assert_l64_fails("x10x", 10);
assert_l64_fails("0x8000000000000000", 16);
assert_l64_fails("-0x8000000000000001", 16);
}
void test_core_strtol__buffer_length_truncates(void)
{
int32_t i32;
int64_t i64;
cl_git_pass(git__strntol32(&i32, "11", 1, NULL, 10));
cl_assert_equal_i(i32, 1);
cl_git_pass(git__strntol64(&i64, "11", 1, NULL, 10));
cl_assert_equal_i(i64, 1);
}
void test_core_strtol__error_message_cuts_off(void)
{
assert_l32_fails("2147483657foobar", 10);
cl_assert(strstr(giterr_last()->message, "2147483657") != NULL);
cl_assert(strstr(giterr_last()->message, "foobar") == NULL);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment