From 2fb1a9f13c0c465c41d8c08366fb8c41dccf2880 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 22 Aug 2005 11:43:58 +0000 Subject: 21678: Unsetting tied parameters caused various crashes --- ChangeLog | 5 +++++ Src/params.c | 19 ++++++++++++++++--- Test/D04parameter.ztst | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4b0d219d7..0aeb201fc 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2005-08-22 Peter Stephenson + + * 21678: Src/params.c, Test/D04parameter.ztst: unsetting + tied parameters was fraught with crashes. + 2005-08-09 Peter Stephenson * 21577: Dan Bullok: Src/Zle/zle_main.c, Src/init.c, 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; } /**/ diff --git a/Test/D04parameter.ztst b/Test/D04parameter.ztst index 7f2ed4670..6623ebd24 100644 --- a/Test/D04parameter.ztst +++ b/Test/D04parameter.ztst @@ -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]] -- cgit 1.4.1