From 95663e936596933d529a648ed3d6c707d1a1dffe Mon Sep 17 00:00:00 2001 From: "Barton E. Schaefer" Date: Mon, 8 Feb 2016 20:50:07 -0800 Subject: 37914: reparse associative array subscripts in "unset" so keys with "[" or "]" may be backslash-escaped Also fix erroneous test case this revealed. --- ChangeLog | 6 ++++++ Src/builtin.c | 30 ++++++++++++++++++------------ Test/E01options.ztst | 2 +- 3 files changed, 25 insertions(+), 13 deletions(-) diff --git a/ChangeLog b/ChangeLog index 76add9f27..7faa5ecaf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -15,6 +15,12 @@ * unposted: ChangeLog: Move the 37678 entry to the correct location (and author). +2016-02-08 Barton E. Schaefer + + * 37914: Src/builtin.c, Test/E01options.ztst: reparse associative + array subscripts in "unset" so keys with "[" or "]" may be + backslash-escaped. Fix erroneous test case this revealed. + 2016-02-07 Dominik Ritter * unposted: Doc/Zsh/mod_complist.yo: complist module docs: diff --git a/Src/builtin.c b/Src/builtin.c index 63f964d3d..4c8fbcdb1 100644 --- a/Src/builtin.c +++ b/Src/builtin.c @@ -3350,15 +3350,24 @@ bin_unset(char *name, char **argv, Options ops, int func) /* do not glob -- unset the given parameter */ queue_signals(); while ((s = *argv++)) { - char *ss = strchr(s, '['); - char *sse = ss; + char *ss = strchr(s, '['), *subscript = 0; if (ss) { - if (skipparens('[', ']', &sse) || *sse) { - zerrnam(name, "%s: invalid parameter name", s); - returnval = 1; - continue; - } + char *sse; *ss = 0; + if ((sse = parse_subscript(ss+1, 1, ']'))) { + *sse = 0; + subscript = dupstring(ss+1); + *sse = ']'; + remnulargs(subscript); + untokenize(subscript); + } + } + if ((ss && !subscript) || !isident(s)) { + if (ss) + *ss = '['; + zerrnam(name, "%s: invalid parameter name", s); + returnval = 1; + continue; } pm = (Param) (paramtab == realparamtab ? /* getnode2() to avoid autoloading */ @@ -3376,11 +3385,8 @@ bin_unset(char *name, char **argv, Options ops, int func) } else if (ss) { if (PM_TYPE(pm->node.flags) == PM_HASHED) { HashTable tht = paramtab; - if ((paramtab = pm->gsu.h->getfn(pm))) { - *--sse = 0; - unsetparam(ss+1); - *sse = ']'; - } + if ((paramtab = pm->gsu.h->getfn(pm))) + unsetparam(subscript); paramtab = tht; } else if (PM_TYPE(pm->node.flags) == PM_SCALAR || PM_TYPE(pm->node.flags) == PM_ARRAY) { diff --git a/Test/E01options.ztst b/Test/E01options.ztst index f27076765..40e96afc9 100644 --- a/Test/E01options.ztst +++ b/Test/E01options.ztst @@ -776,7 +776,7 @@ unsetopt pathdirs pathtestdir/findme path=($oldpath) - unset $oldpath + unset oldpath rm -rf pdt_topdir pathtestdir 0:PATH_DIRS option >File in upper dir -- cgit 1.4.1