From 1a7473cbc1d7009055484360ae5a3a6f8bac0f6f Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 3 Feb 2015 10:31:03 +0000 Subject: 34455: Further gdbm parameter fixes. Fix memory leak with name of parameter. Unset old parameter before opening db as it might close an existing db. --- Src/Modules/db_gdbm.c | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) (limited to 'Src') diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index 2e2bd3a1e..76d4751bf 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -85,14 +85,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) } resource_name = OPT_ARG(ops, 'f'); - - dbf = gdbm_open(resource_name, 0, read_write, 0666, 0); - if(!dbf) { - zwarnnam(nam, "error opening database file %s", resource_name); - return 1; - } - - pmname = ztrdup(*args); + pmname = *args; if ((tied_param = (Param)paramtab->getnode(paramtab, pmname)) && !(tied_param->node.flags & PM_UNSET)) { @@ -100,13 +93,24 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func)) * Unset any existing parameter. Note there's no implicit * "local" here, but if the existing parameter is local * that will be reflected in the new one. + * + * We need to do this before attempting to open the DB + * in case this variable is already tied to a DB. + * + * This can fail if the variable is readonly or restricted. + * We could call unsetparam() and check errflag instead + * of the return status. */ - if (unsetparam_pm(tied_param, 0, 1)) { - zsfree(pmname); - gdbm_close(dbf); + if (unsetparam_pm(tied_param, 0, 1)) return 1; - } } + + dbf = gdbm_open(resource_name, 0, read_write, 0666, 0); + if(!dbf) { + zwarnnam(nam, "error opening database file %s", resource_name); + return 1; + } + if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys, pmflags))) { zwarnnam(nam, "cannot create the requested parameter %s", pmname); -- cgit 1.4.1