From 3bc6e879d89597b3ef16a3a32be214edf2248c32 Mon Sep 17 00:00:00 2001 From: Slendi Date: Sun, 27 Jul 2025 22:21:10 +0300 Subject: [PATCH] Fix some memory leaks Signed-off-by: Slendi --- flake.nix | 1 + src/dcfg.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 3 deletions(-) diff --git a/flake.nix b/flake.nix index d4edbfb..83547b7 100644 --- a/flake.nix +++ b/flake.nix @@ -28,6 +28,7 @@ lldb pkg-config tokei + valgrind ]; }; diff --git a/src/dcfg.c b/src/dcfg.c index ebf5f88..53ca885 100644 --- a/src/dcfg.c +++ b/src/dcfg.c @@ -263,7 +263,14 @@ void dcfg_destroy_instance(dcfg_Instance *instance) { assert(instance); + for (size_t i = 0; i < vector_size(instance->source_pathv); i++) { + free((void *)instance->source_pathv[i].data); + } vector_free(instance->source_pathv); + + for (size_t i = 0; i < vector_size(instance->sourcev); i++) { + free((void *)instance->sourcev[i].data); + } vector_free(instance->sourcev); pthread_mutex_lock(&instance->mtx); @@ -1202,8 +1209,15 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path) StringView str = { .size = size, - .data = ALLOC(size), + .data = ALLOC(size + 1), }; + if (!str.data) { + FREE(abs); + fclose(fp); + snprintf(instance->last_error, sizeof(instance->last_error) - 1, + "Failed to allocate source buffer: %s", strerror(errno)); + return NULL; + } if (!fread((void *)str.data, str.size, 1, fp)) { FREE(abs); FREE((void *)str.data); @@ -1212,6 +1226,7 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path) "fread: %s", strerror(errno)); return NULL; } + ((char *)str.data)[str.size] = '\0'; Lexer lexer; if (!Lexer_init(&lexer, str, abs_sv)) { @@ -1251,6 +1266,8 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path) } instance->last_error[0] = '\0'; + AST_free_parser(ast, &parser); + vector_add(&instance->sourcev, str); v->i_sourcev_idx = vector_size(instance->sourcev) - 1; @@ -1262,8 +1279,44 @@ dcfg_Value *dcfg_parse(dcfg_Instance *instance, dcfg_StringView const file_path) void dcfg_destroy(dcfg_Value *value) { - (void)value; - // FIXME: Implement + if (!value) + return; + + switch (value->type) { + case dcfg_ValueType_Object: + for (size_t i = 0; i < vector_size(value->v.o.entryv); i++) { + dcfg_destroy(value->v.o.entryv[i].v); + } + vector_free(value->v.o.entryv); + break; + + case dcfg_ValueType_Array: + for (size_t i = 0; i < vector_size(value->v.a.valuev); i++) { + dcfg_destroy(value->v.a.valuev[i]); + } + vector_free(value->v.a.valuev); + break; + + case dcfg_ValueType_Function: + if (!value->v.f.is_builtin) { + dcfg_destroy(value->v.f.v.f.body); + vector_free(value->v.f.v.f.argv); + } + break; + + case dcfg_ValueType_FunctionCall: + dcfg_destroy(value->v.c.function); + for (size_t i = 0; i < vector_size(value->v.c.argv); i++) { + dcfg_destroy(value->v.c.argv[i]); + } + vector_free(value->v.c.argv); + break; + + default: + break; + } + + value->instance->free(value); // https://youtu.be/RgFaK6ZQifE } dcfg_ValueType dcfg_Value_type_ex(dcfg_Value *value, bool evaluate)