Add hex_symboltable_destroy function to manage symbol table memory; prevents memory leaks and ensures proper cleanup.
h3rald h3rald@h3rald.com
Wed, 10 Sep 2025 18:27:23 +0200
4 files changed,
74 insertions(+),
11 deletions(-)
M
src/hex.c
→
src/hex.c
@@ -2124,6 +2124,28 @@
return copy; } +void hex_symboltable_destroy(hex_symbol_table_t *table) +{ + if (!table) + { + return; + } + if (table->symbols) + { + for (uint16_t i = 0; i < table->count; ++i) + { + if (table->symbols[i]) + { + free(table->symbols[i]); + table->symbols[i] = NULL; + } + } + free(table->symbols); + table->symbols = NULL; + } + free(table); +} + /* File: src/opcodes.c */ #line 1 "src/opcodes.c" #ifndef HEX_H@@ -4275,15 +4297,24 @@ for (size_t i = 0; i < item->quotation_size; i++)
{ bytecode[i] = (uint8_t)item->data.quotation_value[i]->data.int_value; } - // Copy the current symbol table before evaluating the bytecode - hex_symbol_table_t *symbol_table_copy = hex_symboltable_copy(ctx); + // Sandbox current symbol table: create working copy, run, then discard mutations + hex_symbol_table_t *original_table = ctx->symbol_table; + hex_symbol_table_t *working_copy = hex_symboltable_copy(ctx); + if (!working_copy) + { + free(bytecode); + HEX_FREE(ctx, item); + HEX_FREE(ctx, file); + return 1; + } + ctx->symbol_table = working_copy; int result = hex_interpret_bytecode(ctx, bytecode, item->quotation_size, file->data.str_value); - // Restore the original symbol table - ctx->symbol_table = symbol_table_copy; + hex_symboltable_destroy(ctx->symbol_table); + ctx->symbol_table = original_table; free(bytecode); HEX_FREE(ctx, item); HEX_FREE(ctx, file); - return result; // NOTE: potential leak of mutated symbol table not restored (pre-existing design) + return result; } else {@@ -7406,4 +7437,3 @@
hex_destroy(ctx); return 0; } -
M
src/hex.h
→
src/hex.h
@@ -423,6 +423,7 @@ char *hex_symboltable_get_value(hex_context_t *ctx, uint16_t index);
int hex_decode_bytecode_symboltable(hex_context_t *ctx, uint8_t **bytecode, size_t *size, size_t count); uint8_t *hex_encode_bytecode_symboltable(hex_context_t *ctx, size_t *out_size); hex_symbol_table_t *hex_symboltable_copy(hex_context_t *ctx); +void hex_symboltable_destroy(hex_symbol_table_t *table); // REPL and initialization void hex_register_symbols(hex_context_t *ctx);
M
src/symbols.c
→
src/symbols.c
@@ -310,15 +310,25 @@ for (size_t i = 0; i < item->quotation_size; i++)
{ bytecode[i] = (uint8_t)item->data.quotation_value[i]->data.int_value; } - // Copy the current symbol table before evaluating the bytecode - hex_symbol_table_t *symbol_table_copy = hex_symboltable_copy(ctx); + // Sandbox: save current table pointer; create a working copy to mutate + hex_symbol_table_t *original_table = ctx->symbol_table; + hex_symbol_table_t *working_copy = hex_symboltable_copy(ctx); + if (!working_copy) + { + free(bytecode); + HEX_FREE(ctx, item); + HEX_FREE(ctx, file); + return 1; + } + ctx->symbol_table = working_copy; int result = hex_interpret_bytecode(ctx, bytecode, item->quotation_size, file->data.str_value); - // Restore the original symbol table - ctx->symbol_table = symbol_table_copy; + // Destroy mutated working copy and restore original + hex_symboltable_destroy(ctx->symbol_table); + ctx->symbol_table = original_table; free(bytecode); HEX_FREE(ctx, item); HEX_FREE(ctx, file); - return result; // NOTE: potential leak of mutated symbol table not restored (pre-existing design) + return result; } else {
M
src/symboltable.c
→
src/symboltable.c
@@ -143,3 +143,25 @@ }
return copy; } + +void hex_symboltable_destroy(hex_symbol_table_t *table) +{ + if (!table) + { + return; + } + if (table->symbols) + { + for (uint16_t i = 0; i < table->count; ++i) + { + if (table->symbols[i]) + { + free(table->symbols[i]); + table->symbols[i] = NULL; + } + } + free(table->symbols); + table->symbols = NULL; + } + free(table); +}