Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Bug in alias expansion

On Fri, 13 Nov 2015 13:03:52 -0500
Kynn Jones <kynnjo@xxxxxxxxx> wrote:
> % typeset -A frobozz
> % alias -g foo='echo xyz'
> % frobozz[$(foo)]=9
> zsh: not an identifier: frobozz[$(fooech9

This is somewhere in the vicinity of parse_subscript().  That's called
both from isident() and getindex(); I got as far as the case called from
isident(), but it may be the second one gets called, too.  The
suspicious bit in parse_subscript() is this:

    lexbuf.len = 0;
    lexbuf.ptr = tokstr = s;
    lexbuf.siz = l + 1;
    err = dquote_parse(endchar, sub);
    if (err) {
	err = *lexbuf.ptr;
	*lexbuf.ptr = '\0';
	*lexbuf.ptr = err;
	s = NULL;
    } else {
	s = lexbuf.ptr;

This is assuming the tokstr you get back is the same you sent down,
which it may not because it might need reallocating --- it does indeed
in this case because we are expanding an alias inside.  It confused me a
bit that it's only the end of the string (s, from lexbuf.ptr) that's
being passed back, but that's presumably because it's assuming the start
doesn't move, which is the (or an) erroneous assumption.  It's possible
the fix therefore is simply ensuring that both the start and the end of
the string are pased back and the start passed in forgotten.

Howver, I don't really understand the !ss[1] test (ss is the pointer
passed back) in isident(): it seems to assume the ']' or whatever else
comes at the end of the LHS of the assignment, has been separated off
from anything else, which possibly happens higher up.  When I walked
through this there didn't appear to be any reason why the next character
would be a null since I couldn't see dquote_parse() adding one and I
don't think we've even got that far in reading the input supplied for
this case (as it's only parsing as far as endchar) --- but this may be
part of the same assumption that we've still got the string passed in
down below.  So it's possible it's making even dodgier assumptions that
if you write the output first then something magic is going to happen
about the later parts of it, which it doesn't always.  (Note that the
input is at least a duplicated version of the string being used as the
output area, it's not the "s" in the chunk above itself.)  This might,
for example, be a shortcut instead of testing for end of input after the
']'.  So possibly making parse_subscript() get the next input and look
to see if it's after the end. then passing that back, is also necessary.

I don't know why this works in other contexts.

dquote_parse() has got some comments at the top that look like me trying
to work out what the heck it actually does, which is a bad sign.

Note initial parsing worked OK --- it's got as far as attempting to
evaluate the subscript for the assignment.  Sot it must be broken
assumptions later on rather than failure in the loewr layers.


Messages sorted by: Reverse Date, Date, Thread, Author