diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/commit_list.c | 4 | ||||
| -rw-r--r-- | src/config.c | 2 | ||||
| -rw-r--r-- | src/index.c | 2 | ||||
| -rw-r--r-- | src/rebase.c | 2 | ||||
| -rw-r--r-- | src/revparse.c | 5 | ||||
| -rw-r--r-- | src/signature.c | 6 | ||||
| -rw-r--r-- | src/streams/curl.c | 2 | ||||
| -rw-r--r-- | src/transports/smart_pkt.c | 2 | ||||
| -rw-r--r-- | src/transports/winhttp.c | 3 | ||||
| -rw-r--r-- | src/tree-cache.c | 4 | ||||
| -rw-r--r-- | src/util.c | 38 | ||||
| -rw-r--r-- | src/util.h | 2 |
12 files changed, 39 insertions, 33 deletions
diff --git a/src/commit_list.c b/src/commit_list.c index 96bd9dc15..b4313eed2 100644 --- a/src/commit_list.c +++ b/src/commit_list.c @@ -171,7 +171,9 @@ static int commit_quick_parse( 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"); commit->time = commit_time; diff --git a/src/config.c b/src/config.c index 8d2e12f98..0837500f5 100644 --- a/src/config.c +++ b/src/config.c @@ -1300,7 +1300,7 @@ int git_config_parse_int64(int64_t *out, const char *value) const char *num_end; 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; switch (*num_end) { diff --git a/src/index.c b/src/index.c index 465efaa4e..8858d23a1 100644 --- a/src/index.c +++ b/src/index.c @@ -2243,7 +2243,7 @@ static int read_reuc(git_index *index, const char *buffer, size_t size) for (i = 0; i < 3; i++) { int64_t tmp; - if (git__strtol64(&tmp, buffer, &endptr, 8) < 0 || + if (git__strntol64(&tmp, buffer, size, &endptr, 8) < 0 || !endptr || endptr == buffer || *endptr || tmp < 0 || tmp > UINT32_MAX) { index_entry_reuc_free(lost); diff --git a/src/rebase.c b/src/rebase.c index bc3c5995c..6503e5fc5 100644 --- a/src/rebase.c +++ b/src/rebase.c @@ -152,7 +152,7 @@ GIT_INLINE(int) rebase_readint( if ((error = rebase_readfile(asc_out, state_path, filename)) < 0) 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); return -1; } diff --git a/src/revparse.c b/src/revparse.c index bdbf87558..df96f9d86 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -128,7 +128,8 @@ static int try_parse_numeric(int *n, const char *curly_braces_content) int32_t content; 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; if (*end_ptr != '\0') @@ -578,7 +579,7 @@ static int extract_how_many(int *n, const char *spec, size_t *pos) } while (spec[(*pos)] == kind && kind == '~'); 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; accumulated += (parsed - 1); diff --git a/src/signature.c b/src/signature.c index 286d0a618..91864bb88 100644 --- a/src/signature.c +++ b/src/signature.c @@ -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_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->email); sig->name = sig->email = NULL; @@ -246,7 +247,8 @@ int git_signature__parse(git_signature *sig, const char **buffer_out, tz_start = time_end + 1; 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 */ offset = 0; } diff --git a/src/streams/curl.c b/src/streams/curl.c index ee13be1dc..3c0af3b04 100644 --- a/src/streams/curl.c +++ b/src/streams/curl.c @@ -330,7 +330,7 @@ int git_curl_stream_new(git_stream **out, const char *host, const char *port) 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); return error; } diff --git a/src/transports/smart_pkt.c b/src/transports/smart_pkt.c index 6a404efe4..fb59c70ec 100644 --- a/src/transports/smart_pkt.c +++ b/src/transports/smart_pkt.c @@ -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; if (len < 0) diff --git a/src/transports/winhttp.c b/src/transports/winhttp.c index 3df892d09..e925dbdc0 100644 --- a/src/transports/winhttp.c +++ b/src/transports/winhttp.c @@ -766,7 +766,8 @@ static int winhttp_connect( t->connection = NULL; /* 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; /* Prepare host */ diff --git a/src/tree-cache.c b/src/tree-cache.c index b331d22a2..c33e6af9e 100644 --- a/src/tree-cache.c +++ b/src/tree-cache.c @@ -91,7 +91,7 @@ static int read_tree_internal(git_tree_cache **out, return -1; /* 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; tree->entry_count = count; @@ -100,7 +100,7 @@ static int read_tree_internal(git_tree_cache **out, goto corrupted; /* 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; tree->children_count = count; 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; } diff --git a/src/util.h b/src/util.h index b6f5b7519..400024373 100644 --- a/src/util.h +++ b/src/util.h @@ -58,9 +58,7 @@ GIT_INLINE(int) git__signum(int val) 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__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); |
