summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtienne Samson <samson.etienne@gmail.com>2018-09-26 19:15:35 +0000
committerPatrick Steinhardt <ps@pks.im>2018-10-26 14:58:51 +0200
commitebb0e37ea69c9009c239b7b6d378f57c7802e012 (patch)
tree4d7cd15dfbe27a3a738f30c5726c3a8d71db0cb0
parent5fc7d59c79d0e4a86de33c4b9e22713123fb16b7 (diff)
downloadlibgit2-ebb0e37ea69c9009c239b7b6d378f57c7802e012.tar.gz
vector: do not malloc 0-length vectors on dup
(cherry picked from commit fa48d2ea7d2d5dc9620e5c9f05ba8d788775582b)
-rw-r--r--src/vector.c18
-rw-r--r--tests/core/vector.c19
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);
+}