diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | Doc/Zsh/compsys.yo | 6 | ||||
-rw-r--r-- | README | 9 | ||||
-rw-r--r-- | Src/Zle/computil.c | 12 |
4 files changed, 26 insertions, 5 deletions
diff --git a/ChangeLog b/ChangeLog index be821de99..4643eda77 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2016-09-06 Daniel Shahaf <d.s@daniel.shahaf.name> + * 39173: Doc/Zsh/compsys.yo, README, Src/Zle/computil.c: + _arguments: Escape colons and backslashes in $opt_args + unambiguously. + * 39171: Completion/Unix/Command/_libvirt: Apply $opt_args-unescaping. diff --git a/Doc/Zsh/compsys.yo b/Doc/Zsh/compsys.yo index 8c7ef0f5a..b2cc39268 100644 --- a/Doc/Zsh/compsys.yo +++ b/Doc/Zsh/compsys.yo @@ -3948,8 +3948,10 @@ command line after the command name excluding all options and their arguments. Options are stored in the associative array `tt(opt_args)' with option names as keys and their arguments as the values. For options that have more than one argument these are -given as one string, separated by colons. All colons in the original -arguments are preceded with backslashes. +given as one string, separated by colons. All colons and backslashes +in the original arguments are preceded with backslashes. (Note: +Zsh 5.2 and older did not escape backslashes in the original string; +see the tt(NEWS) file for details.) The parameter `tt(context)' is set when returning to the calling function to perform an action of the form `tt(->)var(string)'. It is set to an diff --git a/README b/README index 9de5eb4a9..019294e4b 100644 --- a/README +++ b/README @@ -87,6 +87,15 @@ The "f" qualifier has for many years been the documented way of testing file modes; it allows the "and" test ("*(f+1)" is the documented equivalent of "*(1)") as well as many other forms. +5) The completion helper function _arguments now escapes both backslashes +and colons in the values of option arguments when populating the $opt_args +associative array. Previously, colons were escaped with a backslash but +backslashes were not themselves escaped with a backslash, which lead to +ambiguity: if the -x option took two arguments (as in + _arguments : -x:foo:${action}:bar:$action +), it would be impossible to tell from $opt_args whether the command-line +was '-x foo\:bar' or '-x foo\\ bar'. + Incompatibilities between 5.0.8 and 5.2 --------------------------------------- diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c index ecfa2bc34..1c90a543a 100644 --- a/Src/Zle/computil.c +++ b/Src/Zle/computil.c @@ -2310,7 +2310,10 @@ ca_parse_line(Cadef d, int multi, int first) return 0; } -/* Build a colon-list from a list. */ +/* Build a colon-list from a list. + * + * This is only used to populate values of $opt_args. + */ static char * ca_colonlist(LinkList l) @@ -2320,16 +2323,19 @@ ca_colonlist(LinkList l) int len = 0; char *p, *ret, *q; + /* Compute the length to be allocated. */ for (n = firstnode(l); n; incnode(n)) { len++; for (p = (char *) getdata(n); *p; p++) - len += (*p == ':' ? 2 : 1); + len += (*p == ':' || *p == '\\') ? 2 : 1; } ret = q = (char *) zalloc(len); + /* Join L into RET, joining with colons and escaping colons and + * backslashes. */ for (n = firstnode(l); n;) { for (p = (char *) getdata(n); *p; p++) { - if (*p == ':') + if (*p == ':' || *p == '\\') *q++ = '\\'; *q++ = *p; } |