From 635b405c5586cf5a383b0a8d8a8de6c64db6318d Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Mon, 22 Aug 2005 11:43:36 +0000 Subject: [PATCH] 21678: Unsetting tied parameters caused various crashes --- ChangeLog | 3 +++ Src/params.c | 19 ++++++++++++++++--- Test/D04parameter.ztst | 34 ++++++++++++++++++++++++++++++++++ 3 files changed, 53 insertions(+), 3 deletions(-) diff --git a/ChangeLog b/ChangeLog index 587c3f23b..19c899474 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2005-08-22 Peter Stephenson + * 21678: Src/params.c, Test/D04parameter.ztst: unsetting + tied parameters was fraught with crashes. + * 21676: Doc/zmacros.yo, Doc/Zsh/contrib.yo, Functions/Zle/.distfiles, Functions/Zle/insert-composed-char, Functions/Zle/insert-unicode-char: insert-unicode-char is now diff --git a/Src/params.c b/Src/params.c index 396c97c3a..26b3f3133 100644 --- a/Src/params.c +++ b/Src/params.c @@ -2342,6 +2342,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); @@ -2351,13 +2352,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) { @@ -2373,6 +2381,8 @@ unsetparam_pm(Param pm, int altflag, int exp) } unsetparam_pm(altpm, 1, exp); } + + zsfree(altremove); } /* @@ -2438,6 +2448,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; } @@ -2815,6 +2827,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 7a6254300..3ad19368d 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]]