Commit 437f7d69b22324d20fe833aa53119885733029c2

Vicent Marti 2013-12-13T12:41:22

pool: Correct overflow checks Ok, scrap the previous commit. This is the right overflow check that takes care of 64 bit overflow **and** 32-bit overflow, which needs to be considered because the pool malloc can only allocate 32-bit elements in one go.

diff --git a/src/pool.c b/src/pool.c
index a236411..146f118 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -194,6 +194,9 @@ char *git_pool_strndup(git_pool *pool, const char *str, size_t n)
 
 	assert(pool && str && pool->item_size == sizeof(char));
 
+	if ((uint32_t)(n + 1) < n)
+		return NULL;
+
 	if ((ptr = git_pool_malloc(pool, (uint32_t)(n + 1))) != NULL) {
 		memcpy(ptr, str, n);
 		ptr[n] = '\0';
diff --git a/tests/core/pool.c b/tests/core/pool.c
index 3073c4a..7a8b2de 100644
--- a/tests/core/pool.c
+++ b/tests/core/pool.c
@@ -139,7 +139,11 @@ void test_core_pool__strndup_limit(void)
 	git_pool p;
 
 	cl_git_pass(git_pool_init(&p, 1, 100));
-	cl_assert(git_pool_strndup(&p, "foo", -1) == NULL);
+	/* ensure 64 bit doesn't overflow */
+	cl_assert(git_pool_strndup(&p, "foo", (size_t)-1) == NULL);
+
+	/* ensure 32 bit doesn't overflow */
+	cl_assert(git_pool_strndup(&p, "bar", 0xfffffffful + 32) == NULL);
 	git_pool_clear(&p);
 }