Skip to content

Commit ce8e1da

Browse files
committed
Fix leak of fixed huffman lut
1 parent 8fac490 commit ce8e1da

3 files changed

Lines changed: 53 additions & 2 deletions

File tree

include/arena/arena.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,24 @@
44

55
typedef struct Arena Arena;
66

7+
/// Creates a new dynamically-allocated arena
78
Arena* arena_new(size_t block_size);
9+
10+
/// Creates a new arena within an existing buffer. Note that the whole buffer
11+
/// size may not be usable.
12+
Arena* arena_new_in_buffer(void* buffer, size_t buffer_len);
13+
14+
/// Frees the dynamically-allocated arena. If the arena was initialized in a
15+
/// fixed buffer, this will panic.
816
void arena_free(Arena* arena);
917

18+
/// Allocates a region of `size` bytes on the arena, with an alignment of
19+
/// `max_align_t`.
1020
void* arena_alloc(Arena* arena, size_t size);
21+
22+
/// Allocates a region of `size` bytes on the arena with a custom alignment.
1123
void* arena_alloc_align(Arena* arena, size_t size, size_t align);
1224

25+
/// Resets the arena, invalidating everything previously allocated on it. Note
26+
/// that this does not free any memory.
1327
void arena_reset(Arena* arena);

src/arena/arena.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
#include "arena/arena.h"
22

33
#include <stdalign.h>
4+
#include <stdbool.h>
45
#include <stddef.h>
56
#include <stdint.h>
67
#include <stdlib.h>
@@ -51,6 +52,7 @@ struct Arena {
5152
ArenaBlock* blocks;
5253
size_t num_blocks;
5354

55+
bool dynamic_arena;
5456
size_t next_block_size;
5557
};
5658

@@ -63,13 +65,40 @@ Arena* arena_new(size_t block_size) {
6365
RELEASE_ASSERT(arena, "Malloc failed");
6466
arena->blocks = blocks;
6567
arena->num_blocks = 1;
68+
arena->dynamic_arena = true;
6669
arena->next_block_size = block_size;
6770

6871
return arena;
6972
}
7073

74+
Arena* arena_new_in_buffer(void* buffer, size_t buffer_len) {
75+
RELEASE_ASSERT(buffer);
76+
RELEASE_ASSERT(
77+
buffer_len >= sizeof(ArenaBlock),
78+
"Arena must be large enough to store itself"
79+
);
80+
81+
size_t self_size = sizeof(Arena) + sizeof(ArenaBlock);
82+
83+
// Create a single arena-block
84+
ArenaBlock* block = buffer;
85+
block->start = (uintptr_t)buffer + self_size;
86+
block->end = (uintptr_t)buffer + buffer_len;
87+
block->ptr = block->end;
88+
89+
// Create the arena
90+
Arena* arena = (void*)((uint8_t*)buffer + sizeof(ArenaBlock));
91+
arena->blocks = block;
92+
arena->num_blocks = 1;
93+
arena->dynamic_arena = false;
94+
arena->next_block_size = 0;
95+
96+
return arena;
97+
}
98+
7199
void arena_free(Arena* arena) {
72100
RELEASE_ASSERT(arena);
101+
RELEASE_ASSERT(arena->dynamic_arena);
73102

74103
LOG_DIAG(INFO, ARENA, "Freeing arena");
75104

@@ -131,6 +160,10 @@ void* arena_alloc_align(Arena* arena, size_t size, size_t align) {
131160
return (void*)aligned_ptr;
132161
}
133162

163+
if (!arena->dynamic_arena) {
164+
LOG_PANIC("Allocation failed on non-dynamic arena: not enough space");
165+
}
166+
134167
// Create new block
135168
ArenaBlock* new_array =
136169
realloc(arena->blocks, sizeof(ArenaBlock) * (arena->num_blocks + 1));

src/codec/deflate.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,7 @@ static PdfError* decode_dyn_huffman_table_luts(
434434
static DeflateHuffmanLut get_fixed_huffman_lut(void) {
435435
static bool initialized = false;
436436
static DeflateHuffmanLut lut;
437+
static uint8_t arena_backing[4096];
437438

438439
if (!initialized) {
439440
LOG_DIAG(DEBUG, CODEC, "Initializing fixed deflate huffman lut");
@@ -455,8 +456,11 @@ static DeflateHuffmanLut get_fixed_huffman_lut(void) {
455456
bit_lens[i] = 8;
456457
}
457458

458-
Arena* persistent_arena = arena_new(1);
459-
lut = build_deflate_huffman_lut(persistent_arena, bit_lens, 288);
459+
Arena* arena = arena_new_in_buffer(
460+
arena_backing,
461+
sizeof(arena_backing) / sizeof(uint8_t)
462+
);
463+
lut = build_deflate_huffman_lut(arena, bit_lens, 288);
460464
}
461465

462466
return lut;

0 commit comments

Comments
 (0)