about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog14
-rw-r--r--Src/exec.c4
-rw-r--r--Src/module.c35
-rw-r--r--Src/params.c1
4 files changed, 44 insertions, 10 deletions
diff --git a/ChangeLog b/ChangeLog
index 8831f679b..b07f9f34a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2004-03-18  Peter Stephenson  <pws@csr.com>
+
+	* 19657: Src/modules.c: Leak when an autoloadable math function
+	was read in.  Also, it was impossible to autoload multiple math
+	functions from the same library.
+
+	* 19656: Src/exec.c Leak saving and restoring parameters around
+	builtins and functions when set temporarily for that command if
+	the parameter was previously exported.
+
+	* 19655: Src/params.c: the reverse pointer from a tied array
+	to a tied scalar wasn't delete if the array was unset by unsetting
+	the scalar (or probably vice versa).
+
 2004-03-17  Peter Stephenson  <pws@csr.com>
 
 	* unposted: Etc/MACHINES: dlcompat apparently not needed
diff --git a/Src/exec.c b/Src/exec.c
index bb4194d52..4bd6503bf 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -2519,6 +2519,10 @@ save_params(Estate state, Wordcode pc, LinkList *restore_p, LinkList *remove_p)
     while (wc_code(ac = *pc) == WC_ASSIGN) {
 	s = ecrawstr(state->prog, pc + 1, NULL);
 	if ((pm = (Param) paramtab->getnode(paramtab, s))) {
+	    if (pm->env) {
+		delenv(pm->env);
+		pm->env = NULL;
+	    }
 	    if (!(pm->flags & PM_SPECIAL)) {
 		paramtab->removenode(paramtab, s);
 	    } else if (!(pm->flags & PM_READONLY) &&
diff --git a/Src/module.c b/Src/module.c
index 3a89294e5..4a4807a31 100644
--- a/Src/module.c
+++ b/Src/module.c
@@ -2039,6 +2039,19 @@ add_autoparam(char *nam, char *module)
 MathFunc mathfuncs;
 
 /**/
+static void removemathfunc(MathFunc previous, MathFunc current)
+{
+    if (previous)
+	previous->next = current->next;
+    else
+	mathfuncs = current->next;
+
+    zsfree(current->name);
+    zsfree(current->module);
+    zfree(current, sizeof(*current));
+}
+
+/**/
 MathFunc
 getmathfunc(char *name, int autol)
 {
@@ -2049,13 +2062,7 @@ getmathfunc(char *name, int autol)
 	    if (autol && p->module) {
 		char *n = dupstring(p->module);
 
-		if (q)
-		    q->next = p->next;
-		else
-		    mathfuncs = p->next;
-
-		zsfree(p->module);
-		zfree(p, sizeof(*p));
+		removemathfunc(q, p);
 
 		load_module(n);
 
@@ -2071,14 +2078,22 @@ getmathfunc(char *name, int autol)
 mod_export int
 addmathfunc(MathFunc f)
 {
-    MathFunc p;
+    MathFunc p, q = NULL;
 
     if (f->flags & MFF_ADDED)
 	return 1;
 
-    for (p = mathfuncs; p; p = p->next)
-	if (!strcmp(f->name, p->name))
+    for (p = mathfuncs; p; q = p, p = p->next)
+	if (!strcmp(f->name, p->name)) {
+	    if (p->module) {
+		/*
+		 * Autoloadable, replace.
+		 */
+		removemathfunc(q, p);
+		break;
+	    }
 	    return 1;
+	}
 
     f->flags |= MFF_ADDED;
     f->next = mathfuncs;
diff --git a/Src/params.c b/Src/params.c
index 0760146fe..d742a389e 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -2673,6 +2673,7 @@ tiedarrunsetfn(Param pm, int exp)
     zfree(pm->u.data, sizeof(struct tieddata));
     /* paranoia -- shouldn't need these, but in case we reuse the struct... */
     pm->u.data = NULL;
+    zsfree(pm->ename);
     pm->flags &= ~PM_TIED;
 }