1
0
Fork 0
mirror of git://git.code.sf.net/p/zsh/code synced 2024-12-29 16:25:35 +01:00

37128: work around alias expansion trashing subscript parsing

This commit is contained in:
Peter Stephenson 2015-11-17 17:44:12 +00:00
parent bc543abbf6
commit ca0cb17011
3 changed files with 42 additions and 6 deletions

View file

@ -1,5 +1,8 @@
2015-11-17 Peter Stephenson <p.stephenson@samsung.com>
* 37128: Src/lex.c, Test/D06subscript.ztst: work around alias
expansion trashing subcript being parsed.
* 37127 (minor tweak): Doc/Zsh/params.yo: document indexing of
$signals.

View file

@ -1617,7 +1617,7 @@ parsestrnoerr(char **s)
mod_export char *
parse_subscript(char *s, int sub, int endchar)
{
int l = strlen(s), err;
int l = strlen(s), err, toklen;
char *t;
if (!*s || *s == endchar)
@ -1626,18 +1626,34 @@ parse_subscript(char *s, int sub, int endchar)
untokenize(t = dupstring(s));
inpush(t, 0, NULL);
strinbeg(0);
/*
* Warning to Future Generations:
*
* This way of passing the subscript through the lexer is brittle.
* Code above this for several layers assumes that when we tokenise
* the input it goes into the same place as the original string.
* However, the lexer may overwrite later bits of the string or
* reallocate it, in particular when expanding aliaes. To get
* around this, we copy the string and then copy it back. This is a
* bit more robust but still relies on the underlying assumption of
* length preservation.
*/
lexbuf.len = 0;
lexbuf.ptr = tokstr = s;
lexbuf.ptr = tokstr = dupstring(s);
lexbuf.siz = l + 1;
err = dquote_parse(endchar, sub);
toklen = (int)(lexbuf.ptr - tokstr);
DPUTS(toklen > l, "Bad length for parsed subscript");
memcpy(s, tokstr, toklen);
if (err) {
err = *lexbuf.ptr;
*lexbuf.ptr = '\0';
char *strend = s + toklen;
err = *strend;
*strend = '\0';
untokenize(s);
*lexbuf.ptr = err;
*strend = err;
s = NULL;
} else {
s = lexbuf.ptr;
s += toklen;
}
strinend();
inpop();

View file

@ -249,3 +249,20 @@
string[0]=!
1:Can't set only element zero of string
?(eval):1: string: assignment to invalid subscript range
typeset -A assoc=(leader topcat officer dibble sidekick choochoo)
alias myind='echo leader' myletter='echo 1' myletter2='echo 4'
print ${assoc[$(myind)]}
print $assoc[$(myind)]
print ${assoc[$(myind)][$(myletter)]}${assoc[$(myind)][$(myletter2)]}
assoc[$(myind)]='of the gang'
print ${assoc[$(myind)]}
print $assoc[$(myind)]
print $assoc[leader]
0: Parsing subscript with non-trivial tokenisation
>topcat
>topcat
>tc
>of the gang
>of the gang
>of the gang