about summary refs log tree commit diff
path: root/Src/params.c
diff options
context:
space:
mode:
authorPeter Stephenson <pws@users.sourceforge.net>2005-08-22 11:43:58 +0000
committerPeter Stephenson <pws@users.sourceforge.net>2005-08-22 11:43:58 +0000
commit2fb1a9f13c0c465c41d8c08366fb8c41dccf2880 (patch)
tree1dfd3bd93762f67168e4383bbcf35b94bd93ca53 /Src/params.c
parent50826130a47ba331306f479187d689bcf06f9e2c (diff)
downloadzsh-2fb1a9f13c0c465c41d8c08366fb8c41dccf2880.tar.gz
zsh-2fb1a9f13c0c465c41d8c08366fb8c41dccf2880.tar.xz
zsh-2fb1a9f13c0c465c41d8c08366fb8c41dccf2880.zip
21678: Unsetting tied parameters caused various crashes
Diffstat (limited to 'Src/params.c')
-rw-r--r--Src/params.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/Src/params.c b/Src/params.c
index 7f91bd048..80647aa28 100644
--- a/Src/params.c
+++ b/Src/params.c
@@ -2329,6 +2329,7 @@ mod_export int
 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);
@@ -2338,13 +2339,20 @@ unsetparam_pm(Param pm, int altflag, int exp)
 	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) {
@@ -2360,6 +2368,8 @@ unsetparam_pm(Param pm, int altflag, int exp)
 	    }
 	    unsetparam_pm(altpm, 1, exp);
 	}
+
+	zsfree(altremove);
     }
 
     /*
@@ -2425,6 +2435,8 @@ stdunsetfn(Param pm, UNUSED(int exp))
 	    	pm->u.str = NULL;
 	    break;
     }
+    if (!(pm->flags & PM_SPECIAL))
+	pm->flags &= ~PM_TIED;
     pm->flags |= PM_UNSET;
 }
 
@@ -2802,6 +2814,7 @@ tiedarrunsetfn(Param pm, UNUSED(int exp))
     zsfree(pm->ename);
     pm->ename = NULL;
     pm->flags &= ~PM_TIED;
+    pm->flags |= PM_UNSET;
 }
 
 /**/