]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: t_get_bytes_available() - Fix return value when current_block is almost full
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Wed, 31 Mar 2021 11:40:12 +0000 (14:40 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Tue, 4 May 2021 07:02:35 +0000 (07:02 +0000)
src/lib/data-stack.c
src/lib/test-data-stack.c

index 756e856fc2276240e2df1530815d0ff6a224ae4d..201296e30b92e3665c982d027241fff68be68be1 100644 (file)
@@ -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)
index 34fc4fcad680528ea271ccf5993cd9675b445795..c6f22a51cb6d36d82bc9084187a0afee903d5d1d 100644 (file)
@@ -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);