From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10710 invoked by alias); 15 Nov 2015 20:09:34 -0000 Mailing-List: contact zsh-workers-help@zsh.org; run by ezmlm Precedence: bulk X-No-Archive: yes List-Id: Zsh Workers List List-Post: List-Help: X-Seq: 37120 Received: (qmail 28908 invoked from network); 15 Nov 2015 20:09:32 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on f.primenet.com.au X-Spam-Level: X-Spam-Status: No, score=-1.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.0 X-Originating-IP: [86.6.158.222] X-Spam: 0 X-Authority: v=2.1 cv=TYVrzkkh c=1 sm=1 tr=0 a=2SBOh4l1h08DI0L+aujZyQ==:117 a=2SBOh4l1h08DI0L+aujZyQ==:17 a=NLZqzBF-AAAA:8 a=kj9zAlcOel0A:10 a=pGLkceISAAAA:8 a=w02zJn46R2kOS-3V4NQA:9 a=CjuIK1q_8ugA:10 Date: Sun, 15 Nov 2015 20:03:56 +0000 From: Peter Stephenson To: zsh-workers@zsh.org Subject: Re: Bug in alias expansion Message-ID: <20151115200356.0f3a80a2@ntlworld.com> In-Reply-To: References: X-Mailer: Claws Mail 3.11.1 (GTK+ 2.24.28; x86_64-redhat-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit On Fri, 13 Nov 2015 13:03:52 -0500 Kynn Jones 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: strinbeg(0); lexbuf.len = 0; lexbuf.ptr = tokstr = s; lexbuf.siz = l + 1; err = dquote_parse(endchar, sub); if (err) { err = *lexbuf.ptr; *lexbuf.ptr = '\0'; untokenize(s); *lexbuf.ptr = err; s = NULL; } else { s = lexbuf.ptr; } strinend(); 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. pws