diff options
author | Barton E. Schaefer <schaefer@zsh.org> | 2016-02-08 20:50:07 -0800 |
---|---|---|
committer | Barton E. Schaefer <schaefer@zsh.org> | 2016-02-08 20:52:11 -0800 |
commit | 95663e936596933d529a648ed3d6c707d1a1dffe (patch) | |
tree | 1722c6eba2d19384956f6c8ac8a3557b503eedcf /Src | |
parent | 8a59aed6967b5283cbf0c7d32559b11d3a841a37 (diff) | |
download | zsh-95663e936596933d529a648ed3d6c707d1a1dffe.tar.gz zsh-95663e936596933d529a648ed3d6c707d1a1dffe.tar.xz zsh-95663e936596933d529a648ed3d6c707d1a1dffe.zip |
37914: reparse associative array subscripts in "unset" so keys with "[" or "]" may be backslash-escaped
Also fix erroneous test case this revealed.
Diffstat (limited to 'Src')
-rw-r--r-- | Src/builtin.c | 30 |
1 files changed, 18 insertions, 12 deletions
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) { |