mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-01-01 05:16:05 +01:00
37128: work around alias expansion trashing subscript parsing
This commit is contained in:
parent
bc543abbf6
commit
ca0cb17011
3 changed files with 42 additions and 6 deletions
|
@ -1,5 +1,8 @@
|
||||||
2015-11-17 Peter Stephenson <p.stephenson@samsung.com>
|
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
|
* 37127 (minor tweak): Doc/Zsh/params.yo: document indexing of
|
||||||
$signals.
|
$signals.
|
||||||
|
|
||||||
|
|
28
Src/lex.c
28
Src/lex.c
|
@ -1617,7 +1617,7 @@ parsestrnoerr(char **s)
|
||||||
mod_export char *
|
mod_export char *
|
||||||
parse_subscript(char *s, int sub, int endchar)
|
parse_subscript(char *s, int sub, int endchar)
|
||||||
{
|
{
|
||||||
int l = strlen(s), err;
|
int l = strlen(s), err, toklen;
|
||||||
char *t;
|
char *t;
|
||||||
|
|
||||||
if (!*s || *s == endchar)
|
if (!*s || *s == endchar)
|
||||||
|
@ -1626,18 +1626,34 @@ parse_subscript(char *s, int sub, int endchar)
|
||||||
untokenize(t = dupstring(s));
|
untokenize(t = dupstring(s));
|
||||||
inpush(t, 0, NULL);
|
inpush(t, 0, NULL);
|
||||||
strinbeg(0);
|
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.len = 0;
|
||||||
lexbuf.ptr = tokstr = s;
|
lexbuf.ptr = tokstr = dupstring(s);
|
||||||
lexbuf.siz = l + 1;
|
lexbuf.siz = l + 1;
|
||||||
err = dquote_parse(endchar, sub);
|
err = dquote_parse(endchar, sub);
|
||||||
|
toklen = (int)(lexbuf.ptr - tokstr);
|
||||||
|
DPUTS(toklen > l, "Bad length for parsed subscript");
|
||||||
|
memcpy(s, tokstr, toklen);
|
||||||
if (err) {
|
if (err) {
|
||||||
err = *lexbuf.ptr;
|
char *strend = s + toklen;
|
||||||
*lexbuf.ptr = '\0';
|
err = *strend;
|
||||||
|
*strend = '\0';
|
||||||
untokenize(s);
|
untokenize(s);
|
||||||
*lexbuf.ptr = err;
|
*strend = err;
|
||||||
s = NULL;
|
s = NULL;
|
||||||
} else {
|
} else {
|
||||||
s = lexbuf.ptr;
|
s += toklen;
|
||||||
}
|
}
|
||||||
strinend();
|
strinend();
|
||||||
inpop();
|
inpop();
|
||||||
|
|
|
@ -249,3 +249,20 @@
|
||||||
string[0]=!
|
string[0]=!
|
||||||
1:Can't set only element zero of string
|
1:Can't set only element zero of string
|
||||||
?(eval):1: string: assignment to invalid subscript range
|
?(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
|
||||||
|
|
Loading…
Reference in a new issue