From b5b15e1d415cb8255a9ba3e8d59ad25f47b057c7 Mon Sep 17 00:00:00 2001 From: Timo Sirainen Date: Wed, 31 Mar 2021 11:56:10 +0300 Subject: [PATCH] lib: Add data_stack_frame_contains() --- src/lib/data-stack.c | 43 +++++++++++++++++++++++++++++++++++++++++++ src/lib/data-stack.h | 3 +++ 2 files changed, 46 insertions(+) diff --git a/src/lib/data-stack.c b/src/lib/data-stack.c index a0d2581dd7..85b284d8eb 100644 --- a/src/lib/data-stack.c +++ b/src/lib/data-stack.c @@ -580,6 +580,49 @@ void data_stack_set_clean_after_pop(bool enable ATTR_UNUSED) #endif } +bool data_stack_frame_contains(data_stack_frame_t *id, const void *_ptr) +{ + const unsigned char *block_data, *ptr = _ptr; + const struct stack_block *block; + unsigned int wanted_frame_id; + size_t block_start_pos, block_used; + + /* first handle the fast path - NULL can never be within the frame */ + if (ptr == NULL) + return FALSE; + +#ifndef STATIC_CHECKER + wanted_frame_id = *id; +#else + wanted_frame_id = (*id)->id; +#endif + /* Too much effort to support more than the latest frame. + It's the only thing that is currently needed anyway. */ + i_assert(wanted_frame_id+1 == data_stack_frame_id); + block = current_frame_block->block[frame_pos]; + i_assert(block != NULL); + + /* See if it's in the frame's first block. Only the data after + block_start_pos belong to this frame. */ + block_data = STACK_BLOCK_DATA(block); + block_start_pos = block->size - + current_frame_block->block_space_left[frame_pos]; + block_used = block->size - block->left; + if (ptr >= block_data + block_start_pos && + ptr <= block_data + block_used) + return TRUE; + + /* See if it's in the other blocks. All the data in them belong to + this frame. */ + for (block = block->next; block != NULL; block = block->next) { + block_data = STACK_BLOCK_DATA(block); + block_used = block->size - block->left; + if (ptr >= block_data && ptr < block_data + block_used) + return TRUE; + } + return FALSE; +} + size_t data_stack_get_alloc_size(void) { struct stack_block *block; diff --git a/src/lib/data-stack.h b/src/lib/data-stack.h index a4f4980efb..3f3d41ec4e 100644 --- a/src/lib/data-stack.h +++ b/src/lib/data-stack.h @@ -116,6 +116,9 @@ void t_buffer_alloc_last_full(void); /* If enabled, all the used memory is cleared after t_pop(). */ void data_stack_set_clean_after_pop(bool enable); +/* Returns TRUE if ptr is allocated within the given data stack frame. + Currently this assert-crashes if the data stack frame isn't the latest. */ +bool data_stack_frame_contains(data_stack_frame_t *id, const void *ptr); /* Returns the number of bytes malloc()ated for data stack. */ size_t data_stack_get_alloc_size(void); -- 2.47.3