From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 1858 invoked by alias); 10 May 2016 18:40:47 -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: 38464 Received: (qmail 2290 invoked from network); 10 May 2016 18:40:44 -0000 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) 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.1 Date: Tue, 10 May 2016 18:40:31 +0000 From: Daniel Shahaf To: Bart Schaefer Cc: zsh-workers@zsh.org Subject: Re: Completion in empty double-quotes generates error Message-ID: <20160510184031.GA27856@tarsus.local2> References: <160330110652.ZM1432@torch.brasslantern.com> <20160401053633.GA17993@tarsus.local2> <160401181824.ZM23675@torch.brasslantern.com> <20160402032950.GA10638@tarsus.local2> <160401232021.ZM25900@torch.brasslantern.com> <160402111815.ZM1925@torch.brasslantern.com> <160406121053.ZM31877@torch.brasslantern.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <160406121053.ZM31877@torch.brasslantern.com> User-Agent: Mutt/1.5.23 (2014-03-12) Bart Schaefer wrote on Wed, Apr 06, 2016 at 12:10:53 -0700: > On Apr 2, 11:18am, Bart Schaefer wrote: > } Subject: Re: Completion in empty double-quotes generates error > } > } What would one expect to be completed with the cursor on the "2"? The > } -redirect- special context is for what comes *after* the operator. I > } can think of only two choices: > } > } 1. Complete as if there were an implicit space to the right of the > } cursor. This makes some sense because "2>" is treated as the same > } single token as ">" all alone. > } > } 2. Treat it as an error and simply fail. > } > } Patch below does this > > More specifically, it attempted to do (1). However, this situation is > really nasty -- get_comp_string() repeatedly calls the lexer looking for > the word containing the cursor, but because the lexer treats redirections > as positionally insignficant, there literally is no word containing the > cursor, so get_comp_string() keeps looking and finds the NEXT word (or > the end of the input), which places both wb and we beyond zlemetacs. > > It gets worse still with "{myfd}>", and worse again when completing in > the whitespace between a word and a redirection (because in that last > situation it's correct for the redirection token to be ignored). > > I'm still not entirely sure that the below is correct, i.e. that the > right things would happen if the "Should" comments were replaced with > the appropriate actual code. But this at least handles more cases than > the previous situation. 'tmux new ' segfaults: $ zsh -f % echo $ZSH_PATCHLEVEL zsh-5.2-dev-1-130-g98f670c % autoload compinit % compinit % tmux new 5: compcore.c:1657: expecting 'x' at offset -7 of "x" Program received signal SIGSEGV, Segmentation fault. 0x00007ffff5a030da in check_param (s=0x7ffff7f90188 "x", set=0, test=1) at compcore.c:1108 1108 if (*p == String || *p == Qstring) { (gdb) p p $1 = 0x7ffff7f8ffff (gdb) bt #0 0x00007ffff5a030da in check_param (s=0x7ffff7f90188 "x", set=0, test=1) at compcore.c:1108 #1 0x00007ffff5a0451f in set_comp_sep () at compcore.c:1677 #2 0x00007ffff59fece5 in bin_compset (name=0x7ffff7f900d0 "compset", argv=0x7ffff7f900e0, ops=0x7ffffffe4160, func=0) at complete.c:1031 It bisects to 38248 (which I'm replying to). I didn't have any tmux sessions/processes running while I was reproducing the bug. Cheers, Daniel P.S. With latest master, «sh -c » also segfaults; on the other hand, after «compdef _cmdstring f», «f » doesn't segfault. > The change in gotword() is necessary but of a little concern. AFAICT > we only care about wb when examining the word under the cursor, so it > shouldn't hurt to skip updating it when doing so would violate the > wb <= zlemetacs <= we constraint, but there may be some corner case I > haven't tried that depends on the old behavior. > > > diff --git a/Src/Zle/zle_tricky.c b/Src/Zle/zle_tricky.c > index b1709c1..1d4e1d2 100644 > --- a/Src/Zle/zle_tricky.c > +++ b/Src/Zle/zle_tricky.c > @@ -1161,6 +1161,7 @@ get_comp_string(void) > inpush(dupstrspace(linptr), 0, NULL); > strinbeg(0); > wordpos = cp = rd = ins = oins = linarr = parct = ia = redirpos = 0; > + we = wb = zlemetacs; > tt0 = NULLTOK; > > /* This loop is possibly the wrong way to do this. It goes through * > @@ -1238,6 +1239,20 @@ get_comp_string(void) > /* Record if we haven't had the command word yet */ > if (wordpos == redirpos) > redirpos++; > + if (zlemetacs < (zlemetall - inbufct) && > + zlemetacs >= wordbeg && wb == we) { > + /* Cursor is in the middle of a redirection, treat as a word */ > + we = zlemetall - (inbufct + addedx); > + if (addedx && we > wb) { > + /* Assume we are in {param}> form, wb points at "{" */ > + wb++; > + /* Should complete parameter names here */ > + } else { > + /* In "2>" form, zlemetacs points at "2" */ > + wb = zlemetacs; > + /* Should insert a space under cursor here */ > + } > + } > } > if (tok == DINPAR) > tokstr = NULL; > diff --git a/Src/lex.c b/Src/lex.c > index d4132fe..25b372a 100644 > --- a/Src/lex.c > +++ b/Src/lex.c > @@ -1789,9 +1789,13 @@ parse_subst_string(char *s) > static void > gotword(void) > { > - we = zlemetall + 1 - inbufct + (addedx == 2 ? 1 : 0); > - if (zlemetacs <= we) { > - wb = zlemetall - wordbeg + addedx; > + int nwe = zlemetall + 1 - inbufct + (addedx == 2 ? 1 : 0); > + if (zlemetacs <= nwe) { > + int nwb = zlemetall - wordbeg + addedx; > + if (zlemetacs >= nwb) { > + wb = nwb; > + we = nwe; > + } > lexflags = 0; > } > } >