aboutsummaryrefslogtreecommitdiffstats
path: root/epan/wmem/wmem_allocator_block.c
diff options
context:
space:
mode:
authorEvan Huus <eapache@gmail.com>2013-03-08 17:51:45 +0000
committerEvan Huus <eapache@gmail.com>2013-03-08 17:51:45 +0000
commit1a78a717ed0bb5c696d8b03c8020db908618920b (patch)
tree499c89815a5cabd528e7ec45c0b43c98243cf296 /epan/wmem/wmem_allocator_block.c
parent4237d33ab8cca07bd3d79cd078a9db513b476bfd (diff)
Should fix assertion failure seen by Anders on -dev.
https://www.wireshark.org/lists/wireshark-dev/201303/msg00081.html svn path=/trunk/; revision=48193
Diffstat (limited to 'epan/wmem/wmem_allocator_block.c')
-rw-r--r--epan/wmem/wmem_allocator_block.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/epan/wmem/wmem_allocator_block.c b/epan/wmem/wmem_allocator_block.c
index 608c3fc6d8..9e0b4cbcd3 100644
--- a/epan/wmem/wmem_allocator_block.c
+++ b/epan/wmem/wmem_allocator_block.c
@@ -357,6 +357,18 @@ wmem_block_split_free_chunk(wmem_block_allocator_t *allocator,
last = chunk->last;
available = chunk->len;
+ if (available < (sizeof(wmem_block_chunk_t) + aligned_size) +
+ (sizeof(wmem_block_chunk_t) + sizeof(wmem_block_free_t))) {
+ /* If the available space is not enought to store the first part
+ * (header + size) AND the second part (header + free_header) then
+ * simply remove the current chunk from the free list. Do it now before
+ * we start messing with header values and confuse things.
+ *
+ * If we do have room, we reuse the free_header from our current chunk
+ * later on, so we don't have to do a full remove/insert. */
+ wmem_block_remove_from_free_list(allocator, chunk);
+ }
+
/* set new values for chunk */
chunk->len = (guint32) (aligned_size + sizeof(wmem_block_chunk_t));
chunk->last = FALSE;
@@ -366,7 +378,7 @@ wmem_block_split_free_chunk(wmem_block_allocator_t *allocator,
extra = WMEM_CHUNK_NEXT(chunk);
available -= (aligned_size + sizeof(wmem_block_chunk_t));
- if (available > sizeof(wmem_block_chunk_t) + sizeof(wmem_block_free_t)) {
+ if (available >= sizeof(wmem_block_chunk_t) + sizeof(wmem_block_free_t)) {
/* If the new block has room for the free header (in which case the old
* bigger one must have as well) then we move the free chunk's address
* without changing its location in the free list so that for large
@@ -550,6 +562,10 @@ wmem_block_alloc(void *private_data, const size_t size)
/* if our split reduced our size too much, something went wrong */
g_assert(size <= WMEM_CHUNK_DATA_LEN(chunk));
+ /* the resulting chunk should not be in the free list */
+ g_assert(chunk != allocator->free_list_head);
+ g_assert(chunk != allocator->free_insert_point);
+
/* mark it as used */
chunk->used = TRUE;