Module: sip-router
Branch: master
Commit: 47daa2e1174376fa94b858ea9473b868161e7341
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=47daa2e…
Author: Miklos Tirpak <miklos(a)iptel.org>
Committer: Miklos Tirpak <miklos(a)iptel.org>
Date: Tue Jan 4 11:14:30 2011 +0100
cfg framework: mem leak in del_group_inst is corrected
cfg_del_group_inst() did not free the strings that were
set within the group instance. When the group instance was
deleted, the strings left allocated.
---
cfg/cfg_ctx.c | 36 +++++++++++++++++++++++++++++++++---
1 files changed, 33 insertions(+), 3 deletions(-)
diff --git a/cfg/cfg_ctx.c b/cfg/cfg_ctx.c
index b23925c..5fe2dc6 100644
--- a/cfg/cfg_ctx.c
+++ b/cfg/cfg_ctx.c
@@ -1521,6 +1521,8 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned int
group_id)
cfg_block_t *block = NULL;
void **replaced = NULL;
cfg_group_inst_t *new_array = NULL, *group_inst;
+ cfg_mapping_t *var;
+ int i, num;
/* verify the context even if we do not need it now
to make sure that a cfg driver has called the function
@@ -1571,13 +1573,41 @@ int cfg_del_group_inst(cfg_ctx_t *ctx, str *group_name, unsigned
int group_id)
/* prepare the array of the replaced strings,
and replaced group instances,
they will be freed when the old block is freed */
- replaced = (void **)shm_malloc(sizeof(void *) * 2);
+
+ /* count the number of strings that has to be freed */
+ num = 0;
+ for (i = 0; i < group->num; i++) {
+ var = &group->mapping[i];
+ if (CFG_VAR_TEST(group_inst, var)
+ && ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) ==
CFG_VAR_STR))
+ && (*(char **)(group_inst->vars + var->offset) != NULL)
+ )
+ num++;
+ }
+
+ replaced = (void **)shm_malloc(sizeof(void *) * (num + 2));
if (!replaced) {
LOG(L_ERR, "ERROR: cfg_del_group_inst(): not enough shm memory\n");
goto error;
}
- replaced[0] = CFG_GROUP_META(*cfg_global, group)->array;
- replaced[1] = NULL;
+
+ if (num) {
+ /* There was at least one string to free, go though the list again */
+ num = 0;
+ for (i = 0; i < group->num; i++) {
+ var = &group->mapping[i];
+ if (CFG_VAR_TEST(group_inst, var)
+ && ((CFG_VAR_TYPE(var) == CFG_VAR_STRING) || (CFG_VAR_TYPE(var) ==
CFG_VAR_STR))
+ && (*(char **)(group_inst->vars + var->offset) != NULL)
+ ) {
+ replaced[num] = *(char **)(group_inst->vars + var->offset);
+ num++;
+ }
+ }
+ }
+
+ replaced[num] = CFG_GROUP_META(*cfg_global, group)->array;
+ replaced[num+1] = NULL;
}
/* replace the global config with the new one */
cfg_install_global(block, replaced, NULL, NULL);