Commit 367f624311edb2d8cc71e1f61b0c756a452c4cff

Patrick Steinhardt 2018-09-28T11:04:06

Merge pull request #4803 from tiennou/fix/4802 index: release the snapshot instead of freeing the index

diff --git a/src/index.c b/src/index.c
index 0450d9f..465efaa 100644
--- a/src/index.c
+++ b/src/index.c
@@ -3550,7 +3550,7 @@ int git_index_snapshot_new(git_vector *snap, git_index *index)
 	error = git_vector_dup(snap, &index->entries, index->entries._cmp);
 
 	if (error < 0)
-		git_index_free(index);
+		git_index_snapshot_release(snap, index);
 
 	return error;
 }
diff --git a/src/vector.c b/src/vector.c
index b12fa94..98aa7bb 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -32,6 +32,9 @@ GIT_INLINE(int) resize_vector(git_vector *v, size_t new_size)
 {
 	void *new_contents;
 
+	if (new_size == 0)
+		return 0;
+
 	new_contents = git__reallocarray(v->contents, new_size, sizeof(void *));
 	GITERR_CHECK_ALLOC(new_contents);
 
@@ -50,22 +53,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 4e6f6fc..6b8ea57 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);
+}