diff options
author | Edward Thomson <ethomson@microsoft.com> | 2015-09-25 12:41:15 -0400 |
---|---|---|
committer | Edward Thomson <ethomson@github.com> | 2016-05-26 13:01:07 -0500 |
commit | e564fc65b53b67ff0753749caa07b7877fb22420 (patch) | |
tree | acf4564f4c4bfe65d26a543f7727c3dbf99e0055 /src/vector.c | |
parent | 0ff723cc90c258f2b78285e7e4b55352e1bc05cd (diff) | |
download | libgit2-e564fc65b53b67ff0753749caa07b7877fb22420.tar.gz |
git_vector_grow/shrink: correct shrink, and tests
Diffstat (limited to 'src/vector.c')
-rw-r--r-- | src/vector.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/src/vector.c b/src/vector.c index 368467692..5ad8a738c 100644 --- a/src/vector.c +++ b/src/vector.c @@ -7,6 +7,7 @@ #include "common.h" #include "vector.h" +#include "integer.h" /* In elements, not bytes */ #define MIN_ALLOCSIZE 8 @@ -332,17 +333,16 @@ int git_vector_resize_to(git_vector *v, size_t new_length) int git_vector_grow_at(git_vector *v, size_t idx, size_t grow_len) { - size_t new_length = v->length + grow_len; - size_t new_idx = idx + grow_len; + size_t new_length; - assert(grow_len > 0); - assert (idx <= v->length); + assert(grow_len > 0 && idx <= v->length); - if (new_length < v->length || - (new_length > v->_alloc_size && resize_vector(v, new_length) < 0)) + GITERR_CHECK_ALLOC_ADD(&new_length, v->length, grow_len); + + if (new_length > v->_alloc_size && resize_vector(v, new_length) < 0) return -1; - memmove(&v->contents[new_idx], &v->contents[idx], + memmove(&v->contents[idx + grow_len], &v->contents[idx], sizeof(void *) * (v->length - idx)); memset(&v->contents[idx], 0, sizeof(void *) * grow_len); @@ -353,17 +353,18 @@ int git_vector_grow_at(git_vector *v, size_t idx, size_t grow_len) int git_vector_shrink_at(git_vector *v, size_t idx, size_t shrink_len) { size_t new_length = v->length - shrink_len; - size_t end_idx = idx + shrink_len; + size_t end_idx = 0; + + assert(shrink_len > 0); - assert(shrink_len > 0 && shrink_len <= v->length); - assert(idx <= v->length); + if (git__add_sizet_overflow(&end_idx, idx, shrink_len)) + assert(0); - if (new_length > v->length) - return -1; + assert(end_idx <= v->length); - if (idx > v->length) + if (end_idx < v->length) memmove(&v->contents[idx], &v->contents[end_idx], - sizeof(void *) * (v->length - idx)); + sizeof(void *) * (v->length - end_idx)); memset(&v->contents[new_length], 0, sizeof(void *) * shrink_len); |