all repos — hex @ ab6a629701dba6aa7a3353a9c7a63172c728ff4e

A tiny, minimalist, slightly-esoteric concatenative programming lannguage.

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
commit

ab6a629701dba6aa7a3353a9c7a63172c728ff4e

parent

a1f5b97ccce00f4f12cbb65b03601ddcae395858

4 files changed, 74 insertions(+), 11 deletions(-)

jump to
M src/hex.csrc/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.hsrc/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.csrc/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.csrc/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); +}