zsh-workers
 help / color / mirror / code / Atom feed
* segfault in completion when using alias with \ as last character
@ 2013-08-01 14:45 torstenschmits
  2013-08-01 16:25 ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: torstenschmits @ 2013-08-01 14:45 UTC (permalink / raw)
  To: zsh-workers

Tested in 5.0/wheezy and 5.0.2/gentoo.
alias foo='bar\'
foo <tab>
-> segfault.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: segfault in completion when using alias with \ as last character
  2013-08-01 14:45 segfault in completion when using alias with \ as last character torstenschmits
@ 2013-08-01 16:25 ` Bart Schaefer
  2013-08-02  5:49   ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2013-08-01 16:25 UTC (permalink / raw)
  To: zsh-workers

On Aug 1,  4:45pm, torstenschmits@gmail.com wrote:
}
} alias foo='bar\'
} foo <tab>
} -> segfault.

Src/Zle/zle_tricky.c:668: BUG: 0 <= wb <= zlemetacs <= we is not true!

That's right after a call to get_comp_string() which we've just been
messing with for a different segfault, but workers/31611 doesn't have
any effect on this one.

The actual crash is here:

0x080c7da3 in ztrsub (t=0x8c0c5d7 "", 
    s=0x8c32001 <Address 0x8c32001 out of bounds>)
    at ../../zsh-5.0/Src/utils.c:4236
4236            if (*s++ == Meta) {
#0  0x080c7da3 in ztrsub (t=0x8c0c5d7 "", 
    s=0x8c32001 <Address 0x8c32001 out of bounds>)
    at ../../zsh-5.0/Src/utils.c:4236
#1  0x08124699 in docomplete (lst=0)
    at ../../../zsh-5.0/Src/Zle/zle_tricky.c:675
#2  0x08123aa9 in completeword (args=0x815ebe0)
    at ../../../zsh-5.0/Src/Zle/zle_tricky.c:232
#3  0x081239cd in completecall (args=0x815ebe0)
    at ../../../zsh-5.0/Src/Zle/zle_tricky.c:208


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: segfault in completion when using alias with \ as last character
  2013-08-01 16:25 ` Bart Schaefer
@ 2013-08-02  5:49   ` Bart Schaefer
  2013-08-02 15:56     ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Bart Schaefer @ 2013-08-02  5:49 UTC (permalink / raw)
  To: zsh-workers

On Aug 1,  9:25am, Bart Schaefer wrote:
}
} On Aug 1,  4:45pm, torstenschmits@gmail.com wrote:
} }
} } alias foo='bar\'
} } foo <tab>
} } -> segfault.
} 
} Src/Zle/zle_tricky.c:668: BUG: 0 <= wb <= zlemetacs <= we is not true!

The problem appears to be somewhere in the lexer, rather than in the
completion system itself.  Tracing through this, if I use e.g.:

% alias foo='echo'
% foo <TAB>

then in lex.c:gotword() the value of wordbeg is 1, and wb is correctly
calculated.

With foo='bar\', however, wordbeg is 6 so wb ends up negative, and it's
all downhill from there.

The upshot seems to be that the trailing backslash in the expanded
alias causes the space after "foo" on the command line to be consumed
as part of the command word.  In effect, the completion system thinks
the completion is at the beginning of the second word, but the lexer
says no, completion is actually in the middle of the first word, and
docomplete() isn't prepared to deal with that dissonance.

This is handled for history by simply expanding it in place and then
refusing to complete anything if the command line changed, but in the
case of aliases we try try to complete as if the alias were expanded
without actually altering the command line to reveal it.

You can see that the segfault does not happen if there are TWO spaces:

% alias foo='bar\'
% foo  <TAB>
Completing file
Src/               Doc/               config.modules     Config/          
Test/              Makefile           config.modules.sh  Etc/             
config.log         stamp-h            config.status*     config.h         

It seems wrong for gotword() to report wb < 0, but just asserting that
wb = 0 when it computes less than zero still triggers the BUG: warning
(though it correctly causes completion to find no matches and instead
e.g. attempt correction), so there must be other tweaking needed to
get wb, we, zlemetall, and zlemetacs all set properly in this case.


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: segfault in completion when using alias with \ as last character
  2013-08-02  5:49   ` Bart Schaefer
@ 2013-08-02 15:56     ` Bart Schaefer
  0 siblings, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2013-08-02 15:56 UTC (permalink / raw)
  To: zsh-workers

On Aug 1, 10:49pm, Bart Schaefer wrote:
} Subject: Re: segfault in completion when using alias with \ as last charac
}
} The upshot seems to be that the trailing backslash in the expanded
} alias causes the space after "foo" on the command line to be consumed
} as part of the command word.

I've tried a couple of different things and I think we need to take a
step back and figure out what OUGHT to be completed in this case.

I can stop it from segfaulting by tweaking we/wb in gotword(), but then
it completes strange inconsistent things depending on the comparative
lengths of the left=right sides of the alias.  And things get even
stranger if you have further aliases that remove the backslash again
(e.g. alias 'bar\ '=something).

One note:  In the case of the alias, gotword() is actually called more
than once, the first time after parsing 'foo' and the second after
parsing 'bar\'.  For completion purposes, the "correct" values are the
ones from the first call, because they describe the raw command line.
I think lexflags = 0 in gotword is supposed to have something to do
with this, but that doesn't kick in until the second call after the
damage has already been done.  (Also it seems like overkill, why are we
clearing ALL the flags here?)

Aside:  Why is gotword() marked mod_export?  Nothing calls it except
exalias() right there in lex.c.

Back to "what ought we do?" ...

The effect of the alias is going to be to turn the first two words on
the command line into a different single word which is then going to
be treated as the command name.  The only correct completion would be
the tail end of words that form a command after the alias expands,
that is, if "/usr/bin/bar none" were a command, then

% foo <TAB>
% foo none

is the only correct thing to complete, but to get that seemingly un-
quoted space to become part of the word "foo " is a nightmare (and an
edge case that doesn't seem worth a lot of effort).

Maybe we just should have stuck with having aliases always expand like
history does, way back when.


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-08-02 15:57 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-08-01 14:45 segfault in completion when using alias with \ as last character torstenschmits
2013-08-01 16:25 ` Bart Schaefer
2013-08-02  5:49   ` Bart Schaefer
2013-08-02 15:56     ` Bart Schaefer

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).