From: Timo Sirainen Date: Wed, 31 Mar 2021 11:40:12 +0000 (+0300) Subject: lib: t_get_bytes_available() - Fix return value when current_block is almost full X-Git-Tag: 2.3.16~244 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=aff92930fb16f4158e086af7ac7248e84019d23d;p=thirdparty%2Fdovecot%2Fcore.git lib: t_get_bytes_available() - Fix return value when current_block is almost full --- diff --git a/src/lib/data-stack.c b/src/lib/data-stack.c index 756e856fc2..201296e30b 100644 --- a/src/lib/data-stack.c +++ b/src/lib/data-stack.c @@ -534,15 +534,17 @@ t_try_realloc(void *mem, size_t size) size_t t_get_bytes_available(void) { + block_canary_check(current_block); #ifndef DEBUG - const unsigned int extra = MEM_ALIGN_SIZE-1; + const unsigned int min_extra = 0; #else - const unsigned int extra = MEM_ALIGN_SIZE-1 + SENTRY_COUNT + - MEM_ALIGN(sizeof(size_t)); + const unsigned int min_extra = SENTRY_COUNT + MEM_ALIGN(sizeof(size_t)); #endif - block_canary_check(current_block); - return current_block->left < extra ? current_block->left : - current_block->left - extra; + if (current_block->left < min_extra) + return 0; + size_t size = current_block->left - min_extra; + i_assert(ALLOC_SIZE(size) == current_block->left); + return size; } void *t_buffer_get(size_t size) diff --git a/src/lib/test-data-stack.c b/src/lib/test-data-stack.c index 34fc4fcad6..c6f22a51cb 100644 --- a/src/lib/test-data-stack.c +++ b/src/lib/test-data-stack.c @@ -3,6 +3,34 @@ #include "test-lib.h" #include "data-stack.h" +static void test_ds_get_bytes_available(void) +{ + test_begin("data-stack t_get_bytes_available()"); + for (unsigned int i = 0; i < 32; i++) { + size_t orig_avail = t_get_bytes_available(); + size_t avail1; + T_BEGIN { + if (i > 0) + t_malloc_no0(i); + avail1 = t_get_bytes_available(); + t_malloc_no0(avail1); + test_assert_idx(t_get_bytes_available() == 0, i); + t_malloc_no0(1); + test_assert_idx(t_get_bytes_available() > 0, i); + } T_END; + T_BEGIN { + if (i > 0) + t_malloc_no0(i); + size_t avail2 = t_get_bytes_available(); + test_assert_idx(avail1 == avail2, i); + t_malloc_no0(avail2 + 1); + test_assert_idx(t_get_bytes_available() > 0, i); + } T_END; + test_assert_idx(t_get_bytes_available() == orig_avail, i); + } + test_end(); +} + static void test_ds_buffers(void) { test_begin("data-stack buffer growth"); @@ -11,7 +39,7 @@ static void test_ds_buffers(void) unsigned char *p; size_t left = t_get_bytes_available(); while (left < 10000) { - t_malloc_no0(left); /* force a new block */ + t_malloc_no0(left+1); /* force a new block */ left = t_get_bytes_available(); } left -= 64; /* make room for the sentry if DEBUG */ @@ -70,7 +98,7 @@ static void test_ds_realloc() unsigned char *p; size_t left = t_get_bytes_available(); while (left < 10000) { - t_malloc_no0(left); /* force a new block */ + t_malloc_no0(left+1); /* force a new block */ left = t_get_bytes_available(); } left -= 64; /* make room for the sentry if DEBUG */ @@ -207,6 +235,7 @@ static void test_ds_pass_str(void) void test_data_stack(void) { + test_ds_get_bytes_available(); test_ds_buffers(); test_ds_realloc(); test_ds_recursive(20, 80);