From f740f2829a881eed3de9722de4d52f010812fcfd Mon Sep 17 00:00:00 2001 From: Enno Rehling Date: Wed, 14 Oct 2015 20:41:42 +0200 Subject: [PATCH] leak: in tests, when correct message_type doesn't exist, arguments should not leak --- src/kernel/build.c | 10 +++++++++- src/reports.c | 19 ++++++++++++++++++- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/kernel/build.c b/src/kernel/build.c index 931c730f0..bc5df861d 100644 --- a/src/kernel/build.c +++ b/src/kernel/build.c @@ -627,19 +627,27 @@ message *msg_materials_required(unit * u, order * ord, const construction * ctype, int multi) { int c; + message *msg; /* something missing from the list of materials */ resource *reslist = NULL; if (multi <= 0 || multi == INT_MAX) multi = 1; for (c = 0; ctype && ctype->materials[c].number; ++c) { + // TODO: lots of alloc/dealloc calls here (make var_copy_resources take an array) resource *res = malloc(sizeof(resource)); res->number = multi * ctype->materials[c].number / ctype->reqsize; res->type = ctype->materials[c].rtype; res->next = reslist; reslist = res; } - return msg_feedback(u, ord, "build_required", "required", reslist); + msg = msg_feedback(u, ord, "build_required", "required", reslist); + while (reslist) { + resource *res = reslist->next; + free(reslist); + reslist = res; + } + return msg; } int maxbuild(const unit * u, const construction * cons) diff --git a/src/reports.c b/src/reports.c index eed25cd45..f09344ee1 100644 --- a/src/reports.c +++ b/src/reports.c @@ -1733,6 +1733,23 @@ static variant var_copy_items(variant x) return x; } +static variant var_copy_resources(variant x) +{ + resource *rsrc; + resource *rdst = NULL, **rptr = &rdst; + + for (rsrc = (resource *)x.v; rsrc != NULL; rsrc = rsrc->next) { + resource *res = malloc(sizeof(resource)); + res->number = rsrc->number; + res->type = rsrc->type; + *rptr = res; + rptr = &res->next; + } + *rptr = NULL; + x.v = rdst; + return x; +} + static void var_free_resources(variant x) { resource *rsrc = (resource *)x.v; @@ -2295,7 +2312,7 @@ void register_reports(void) register_argtype("int", NULL, NULL, VAR_INT); register_argtype("string", var_free_string, var_copy_string, VAR_VOIDPTR); register_argtype("order", var_free_order, var_copy_order, VAR_VOIDPTR); - register_argtype("resources", var_free_resources, NULL, VAR_VOIDPTR); + register_argtype("resources", var_free_resources, var_copy_resources, VAR_VOIDPTR); register_argtype("items", var_free_resources, var_copy_items, VAR_VOIDPTR); register_argtype("regions", var_free_regions, NULL, VAR_VOIDPTR);