diff options
| author | Patrick Steinhardt <ps@pks.im> | 2019-10-03 09:39:42 +0200 |
|---|---|---|
| committer | Patrick Steinhardt <ps@pks.im> | 2019-10-03 12:23:52 +0200 |
| commit | 5cf17e0f269387f8345201aef482a10c96490d95 (patch) | |
| tree | c9999766ad5a8e7293805bef3a06ad1b4c45a25b /src/commit_list.c | |
| parent | 5988cf34f0c77a426510c3bff665fd8a1e8cceb9 (diff) | |
| download | libgit2-5cf17e0f269387f8345201aef482a10c96490d95.tar.gz | |
commit_list: store in/out-degrees as uint16_t
The commit list's in- and out-degrees are currently stored as `unsigned
short`. When assigning it the value of `git_array_size`, which returns
an `size_t`, this generates a warning on some Win32 platforms due to
loosing precision.
We could just cast the returned value of `git_array_size`, which would
work fine for 99.99% of all cases as commits typically have less than
2^16 parents. For crafted commits though we might end up with a wrong
value, and thus we should definitely check whether the array size
actually fits into the field.
To ease the check, let's convert the fields to store the degrees as
`uint16_t`. We shouldn't rely on such unspecific types anyway, as it may
lead to different behaviour across platforms. Furthermore, this commit
introduces a new `git__is_uint16` function to check whether it actually
fits -- if not, we return an error.
Diffstat (limited to 'src/commit_list.c')
| -rw-r--r-- | src/commit_list.c | 8 |
1 files changed, 7 insertions, 1 deletions
diff --git a/src/commit_list.c b/src/commit_list.c index 209655434..a58a0a7e0 100644 --- a/src/commit_list.c +++ b/src/commit_list.c @@ -114,8 +114,14 @@ static int commit_quick_parse( return error; } + if (!git__is_uint16(git_array_size(commit->parent_ids))) { + git__free(commit); + git_error_set(GIT_ERROR_INVALID, "commit has more than 2^16 parents"); + return -1; + } + node->time = commit->committer->when.time; - node->out_degree = git_array_size(commit->parent_ids); + node->out_degree = (uint16_t) git_array_size(commit->parent_ids); node->parents = alloc_parents(walk, node, node->out_degree); GIT_ERROR_CHECK_ALLOC(node->parents); |
