Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Segfault in zsh 4.2.5 in assignment to array variable tied to unset scalar.



John Reese wrote:
> Howdy.
> 
> ofb:3% zsh --version                                                14:40 o=
> fb:~
> zsh 4.2.5 (i686-pc-linux-gnu)
> ofb:3% STRING=3Da:b                                                   14:40=
>  ofb:~
> ofb:3% typeset -T STRING string                                     14:40 o=
> fb:~
> ofb:3% unset STRING                                                 14:40 o=
> fb:~
> ofb:3% set -A string x y z                                          14:40 o=
> fb:~
> zsh: 18569 segmentation fault  zsh

Thanks for reporting this.

Unfortunately tied parameters are a bit hairy.  This fixes this and a
few other bugs that turned up with the new test.  I've been conservative
to reduce the risk of introducing memory leaks.  (I think there was a
leak caused by the same problem that the parameter didn't get unset
under it's alternative name.)  The patch is actually against the head of
4.3 but I'll apply it to the 4.2 branch.

I've sent this to zsh-workers since there doesn't seem to be anything of
user interest (apart from the existence of the fix).

Index: Src/params.c
===================================================================
RCS file: /cvsroot/zsh/zsh/Src/params.c,v
retrieving revision 1.100
diff -u -r1.100 params.c
--- Src/params.c	8 Aug 2005 16:49:10 -0000	1.100
+++ Src/params.c	22 Aug 2005 11:34:56 -0000
@@ -2342,6 +2342,7 @@
 unsetparam_pm(Param pm, int altflag, int exp)
 {
     Param oldpm, altpm;
+    char *altremove;
 
     if ((pm->flags & PM_READONLY) && pm->level <= locallevel) {
 	zerr("read-only variable: %s", pm->nam, 0);
@@ -2351,13 +2352,20 @@
 	zerr("%s: restricted", pm->nam, 0);
 	return 1;
     }
-    pm->gsu.s->unsetfn(pm, exp);
+
+    if (pm->ename && !altflag)
+	altremove = ztrdup(pm->ename);
+    else
+	altremove = NULL;
+
+    if (!(pm->flags & PM_UNSET))
+	pm->gsu.s->unsetfn(pm, exp);
     if (pm->env)
 	delenv(pm);
 
     /* remove it under its alternate name if necessary */
-    if (pm->ename && !altflag) {
-	altpm = (Param) paramtab->getnode(paramtab, pm->ename);
+    if (altremove) {
+	altpm = (Param) paramtab->getnode(paramtab, altremove);
 	/* tied parameters are at the same local level as each other */
 	oldpm = NULL;
 	while (altpm && altpm->level > pm->level) {
@@ -2373,6 +2381,8 @@
 	    }
 	    unsetparam_pm(altpm, 1, exp);
 	}
+
+	zsfree(altremove);
     }
 
     /*
@@ -2438,6 +2448,8 @@
 	    	pm->u.str = NULL;
 	    break;
     }
+    if (!(pm->flags & PM_SPECIAL))
+	pm->flags &= ~PM_TIED;
     pm->flags |= PM_UNSET;
 }
 
@@ -2815,6 +2827,7 @@
     zsfree(pm->ename);
     pm->ename = NULL;
     pm->flags &= ~PM_TIED;
+    pm->flags |= PM_UNSET;
 }
 
 /**/
Index: Test/D04parameter.ztst
===================================================================
RCS file: /cvsroot/zsh/zsh/Test/D04parameter.ztst,v
retrieving revision 1.11
diff -u -r1.11 D04parameter.ztst
--- Test/D04parameter.ztst	17 Aug 2005 23:45:33 -0000	1.11
+++ Test/D04parameter.ztst	22 Aug 2005 11:34:56 -0000
@@ -568,6 +568,40 @@
 >0
 >/elsewhere /somewhere
 
+  local STRING=a:b
+  typeset -T STRING string
+  print $STRING $string
+  unset STRING
+  set -A string x y z
+  print $STRING $string
+  STRING=a:b
+  typeset -T STRING string
+  print $STRING $string
+  unset STRING
+  set -A string x y z
+  print $STRING $string
+  STRING=a:b
+  typeset -T STRING string
+  print $STRING $string
+  unset string
+  STRING=x:y:z
+  print $STRING $string
+  STRING=a:b
+  typeset -T STRING string
+  print $STRING $string
+  unset string
+  STRING=x:y:z
+  print $STRING $string
+0:Unsetting and recreation of tied normal parameters
+>a:b a b
+>x y z
+>a:b a b
+>x y z
+>a:b a b
+>x:y:z
+>a:b a b
+>x:y:z
+
   string='look for a match in here'
   if [[ ${string%%(#b)(match)*} = "look for a " ]]; then
     print $match[1] $mbegin[1] $mend[1] $string[$mbegin[1],$mend[1]]

-- 
Peter Stephenson <pws@xxxxxxx>                  Software Engineer
CSR PLC, Churchill House, Cambridge Business Park, Cowley Road
Cambridge, CB4 0WZ, UK                          Tel: +44 (0)1223 692070


**********************************************************************
This email and any files transmitted with it are confidential and
intended solely for the use of the individual or entity to whom they
are addressed. If you have received this email in error please notify
the system manager.

**********************************************************************



Messages sorted by: Reverse Date, Date, Thread, Author