about summary refs log tree commit diff
diff options
context:
space:
mode:
authorOliver Kiddle <okiddle@yahoo.co.uk>2018-04-12 23:15:04 +0200
committerOliver Kiddle <okiddle@yahoo.co.uk>2018-04-12 23:15:29 +0200
commit65b265f3c0877823b72ffff6ba1083972c49a3a8 (patch)
tree42f54ce498e887dd73d697ee8fe43674bd728709
parent2c4ec9dab0233afa146f0ad99041194c208e23b7 (diff)
downloadzsh-65b265f3c0877823b72ffff6ba1083972c49a3a8.tar.gz
zsh-65b265f3c0877823b72ffff6ba1083972c49a3a8.tar.xz
zsh-65b265f3c0877823b72ffff6ba1083972c49a3a8.zip
42624 (plus test): avoid freeing memory that's still needed
This was occurring in a multiple function definition where a
function name is duplicated.
-rw-r--r--ChangeLog6
-rw-r--r--Src/exec.c14
-rw-r--r--Test/C04funcdef.ztst10
3 files changed, 25 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog
index 926abf3ea..949fdda57 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2018-04-12  Oliver Kiddle  <okiddle@yahoo.co.uk>
+
+	* 42624 (plus test): Src/exec.c, Test/C04funcdef.ztst: avoid
+	freeing memory that's still needed in multiple function
+	definition that has a duplicated function name
+
 2018-04-11  Peter Stephenson  <p.stephenson@samsung.com>
 
 	* 42623: configure.ac: some extra quotes needed (and some
diff --git a/Src/exec.c b/Src/exec.c
index e154d1249..216057aa7 100644
--- a/Src/exec.c
+++ b/Src/exec.c
@@ -5042,7 +5042,7 @@ execfuncdef(Estate state, Eprog redir_prog)
     Shfunc shf;
     char *s = NULL;
     int signum, nprg, sbeg, nstrs, npats, len, plen, i, htok = 0, ret = 0;
-    int nfunc = 0, anon_func = 0;
+    int anon_func = 0;
     Wordcode beg = state->pc, end;
     Eprog prog;
     Patprog *pp;
@@ -5118,12 +5118,16 @@ execfuncdef(Estate state, Eprog redir_prog)
 	/*
 	 * redir_prog is permanently allocated --- but if
 	 * this function has multiple names we need an additional
-	 * one.
+	 * one. Original redir_prog used with the last name
+	 * because earlier functions are freed in case of duplicate
+	 * names.
 	 */
-	if (nfunc++ && redir_prog)
+	if (names && nonempty(names) && redir_prog)
 	    shf->redir = dupeprog(redir_prog, 0);
-	else
+	else {
 	    shf->redir = redir_prog;
+	    redir_prog = 0;
+	}
 	shfunc_set_sticky(shf);
 
 	if (!names) {
@@ -5203,7 +5207,7 @@ execfuncdef(Estate state, Eprog redir_prog)
     }
     if (!anon_func)
 	setunderscore("");
-    if (!nfunc && redir_prog) {
+    if (redir_prog) {
 	/* For completeness, shouldn't happen */
 	freeeprog(redir_prog);
     }
diff --git a/Test/C04funcdef.ztst b/Test/C04funcdef.ztst
index 5786018e0..3aaf7fb4a 100644
--- a/Test/C04funcdef.ztst
+++ b/Test/C04funcdef.ztst
@@ -43,6 +43,16 @@
 0:Function definition without braces
 >bar
 
+  a a b() {
+    read word
+    print $0: $word
+  } <<<redirection
+  b
+  a
+0:Multiple function definition with duplicate name and redirection
+>b: redirection
+>a: redirection
+
   functions -M m1
   m1() { (( $# )) }
   print $(( m1() ))