summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog6
-rw-r--r--Src/builtin.c30
-rw-r--r--Test/E01options.ztst2
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 <schaefer@zsh.org>
+
+ * 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 <dritter03@googlemail.com>
* 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