Commit 7ff7ca623e9ea8c55cb1dab8ce998dd48c0aeb68

Vicent Marti 2015-11-12T20:51:01

pool: Never return unaligned buffers

diff --git a/src/pool.c b/src/pool.c
index aab63be..e519b75 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -8,7 +8,7 @@ struct git_pool_page {
 	git_pool_page *next;
 	uint32_t size;
 	uint32_t avail;
-	char data[GIT_FLEX_ARRAY];
+	GIT_ALIGN(char data[GIT_FLEX_ARRAY], 8);
 };
 
 static void *pool_alloc_page(git_pool *pool, uint32_t size);
@@ -30,11 +30,8 @@ uint32_t git_pool__system_page_size(void)
 
 void git_pool_init(git_pool *pool, uint32_t item_size)
 {
-	const uint32_t align_size = sizeof(void *) - 1;
 	assert(pool);
-
-	if (item_size > 1)
-		item_size = (item_size + align_size) & ~align_size;
+	assert(item_size >= 1);
 
 	memset(pool, 0, sizeof(git_pool));
 	pool->item_size = item_size;
@@ -98,15 +95,26 @@ static void *pool_alloc(git_pool *pool, uint32_t size)
 	return ptr;
 }
 
+static uint32_t alloc_size(git_pool *pool, uint32_t count)
+{
+	const uint32_t align = sizeof(void *) - 1;
+
+	if (pool->item_size > 1) {
+		const uint32_t item_size = (pool->item_size + align) & ~align;
+		return item_size * count;
+	}
+
+	return (count + align) & ~align;
+}
+
 void *git_pool_malloc(git_pool *pool, uint32_t items)
 {
-	const uint32_t size = items * pool->item_size;
-	return pool_alloc(pool, size);
+	return pool_alloc(pool, alloc_size(pool, items));
 }
 
 void *git_pool_mallocz(git_pool *pool, uint32_t items)
 {
-	const uint32_t size = items * pool->item_size;
+	const uint32_t size = alloc_size(pool, items);
 	void *ptr = pool_alloc(pool, size);
 	if (ptr)
 		memset(ptr, 0x0, size);
diff --git a/tests/core/pool.c b/tests/core/pool.c
index f90adfb..c43c1db 100644
--- a/tests/core/pool.c
+++ b/tests/core/pool.c
@@ -32,7 +32,7 @@ void test_core_pool__1(void)
 		cl_assert(git_pool_malloc(&p, i) != NULL);
 
 	/* with fixed page size, allocation must end up with these values */
-	cl_assert_equal_i(590, git_pool__open_pages(&p));
+	cl_assert_equal_i(591, git_pool__open_pages(&p));
 	git_pool_clear(&p);
 
 	git_pool_init(&p, 1);
@@ -42,7 +42,7 @@ void test_core_pool__1(void)
 		cl_assert(git_pool_malloc(&p, i) != NULL);
 
 	/* with fixed page size, allocation must end up with these values */
-	cl_assert_equal_i(573, git_pool__open_pages(&p));
+	cl_assert_equal_i(sizeof(void *) == 8 ? 575 : 573, git_pool__open_pages(&p));
 	git_pool_clear(&p);
 }