diff options
author | Etienne Samson <samson.etienne@gmail.com> | 2018-09-26 19:15:35 +0000 |
---|---|---|
committer | Patrick Steinhardt <ps@pks.im> | 2018-10-26 14:58:51 +0200 |
commit | ebb0e37ea69c9009c239b7b6d378f57c7802e012 (patch) | |
tree | 4d7cd15dfbe27a3a738f30c5726c3a8d71db0cb0 | |
parent | 5fc7d59c79d0e4a86de33c4b9e22713123fb16b7 (diff) | |
download | libgit2-ebb0e37ea69c9009c239b7b6d378f57c7802e012.tar.gz |
vector: do not malloc 0-length vectors on dup
(cherry picked from commit fa48d2ea7d2d5dc9620e5c9f05ba8d788775582b)
-rw-r--r-- | src/vector.c | 18 | ||||
-rw-r--r-- | tests/core/vector.c | 19 |
2 files changed, 29 insertions, 8 deletions
diff --git a/src/vector.c b/src/vector.c index b12fa942d..aac4863d4 100644 --- a/src/vector.c +++ b/src/vector.c @@ -50,22 +50,24 @@ int git_vector_size_hint(git_vector *v, size_t size_hint) int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp) { - size_t bytes; - assert(v && src); - GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *)); - - v->_alloc_size = src->length; + v->_alloc_size = 0; + v->contents = NULL; v->_cmp = cmp ? cmp : src->_cmp; v->length = src->length; v->flags = src->flags; if (cmp != src->_cmp) git_vector_set_sorted(v, 0); - v->contents = git__malloc(bytes); - GITERR_CHECK_ALLOC(v->contents); - memcpy(v->contents, src->contents, bytes); + if (src->length) { + size_t bytes; + GITERR_CHECK_ALLOC_MULTIPLY(&bytes, src->length, sizeof(void *)); + v->contents = git__malloc(bytes); + GITERR_CHECK_ALLOC(v->contents); + v->_alloc_size = src->length; + memcpy(v->contents, src->contents, bytes); + } return 0; } diff --git a/tests/core/vector.c b/tests/core/vector.c index c2e5d3f34..371c68160 100644 --- a/tests/core/vector.c +++ b/tests/core/vector.c @@ -407,3 +407,22 @@ void test_core_vector__reverse(void) git_vector_free(&v); } + +void test_core_vector__dup_empty_vector(void) +{ + git_vector v = GIT_VECTOR_INIT; + git_vector dup = GIT_VECTOR_INIT; + void *dummy = 0xDEAFBEEB; + + cl_assert_equal_i(0, v.length); + + cl_git_pass(git_vector_dup(&dup, &v, v._cmp)); + cl_assert_equal_i(0, dup._alloc_size); + cl_assert_equal_i(0, dup.length); + + cl_git_pass(git_vector_insert(&dup, dummy)); + cl_assert_equal_i(8, dup._alloc_size); + cl_assert_equal_i(1, dup.length); + + git_vector_free(&dup); +} |