Zsh Mailing List Archive
Messages sorted by:
Reverse Date,
Date,
Thread,
Author
Re: segfault in 'ls' completion
- X-seq: zsh-workers 49656
- From: Zach Riggle <zachriggle@xxxxxxxxx>
- To: Vin Shelton <acs@xxxxxxxxxxxxxxxxxxxx>
- Cc: Oliver Kiddle <opk@xxxxxxx>, Bart Schaefer <schaefer@xxxxxxxxxxxxxxxx>, "Zsh Hackers' List" <zsh-workers@xxxxxxx>
- Subject: Re: segfault in 'ls' completion
- Date: Sat, 18 Dec 2021 04:41:39 -0600
- Archived-at: <https://zsh.org/workers/49656>
- In-reply-to: <CACeGjnWKB7OCUhtwFgPrhSdg4OLL-EmdmAwXVMZunPdSgC=h4w@mail.gmail.com>
- List-id: <zsh-workers.zsh.org>
- References: <CACeGjnWz=vjtE+cZWpzUtcCCRejjsa9rz_026wgt8vQ85UmsNg@mail.gmail.com> <CAH+w=7aMPFXQZvp=ykmsjDu=SRg6DXiFBaEoX9khAycTybxpCQ@mail.gmail.com> <CAH+w=7aTTRGg0B4UtbLL8Jc3UTEB9Ea1i8MDiUxaSrcYYEeriA@mail.gmail.com> <14951-1639612623.711910@AY72.mNNn.Pl2F> <CACeGjnWKB7OCUhtwFgPrhSdg4OLL-EmdmAwXVMZunPdSgC=h4w@mail.gmail.com>
Has anybody actually tried running ZSH with memory safety options
enabled (e.g. Address Sanitizer)?
I assume there is a test suite available to run -- I can build Zsh
from source, but I'm not sure the "right" way to build the tests.
I've subscribed to the zsh-devel mailing list as I expect this is
better suited for that ML.
Zach Riggle
On Wed, Dec 15, 2021 at 9:41 PM Vin Shelton <acs@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> Stops the segfault, and generates a conforming list.
>
> Thanks,
> Vin
>
> On Wed, Dec 15, 2021 at 6:57 PM Oliver Kiddle <opk@xxxxxxx> wrote:
>>
>> Bart Schaefer wrote:
>> > I was able to reproduce this
>>
>> I couldn't initially but as you could, I thought I'd better try again.
>>
>> > reverted to revision e40938c128 (before the workers/49499 changes to
>> > computil.c) and was no longer able to reproduce in that version, but that does
>> > also revert some changes to _arguments.
>>
>> It actually seems it was 49518 / 7cb980b which was only applied
>> yesterday having been posted in October and forgotten. I had a nagging
>> suspicion that I needed to further check over that. My mistake was
>> mixing up hex and decimal when looking at the ASCII table to work out
>> how to rearrange the single character option letters within the lookup
>> array. 20 should have been 0x20 or 32.
>>
>> 'y' appears before the tab and the word starts with something that isn't
>> '-'. So it uses the + options offset which are later and as y is within
>> the difference between decimal and hex 20 from the end of the characters
>> this caused it index beyond the end of the array.
>>
>> Following this, I also wondered what it's doing strcmping '/usr/libpy'
>> against every possible ls option. That's nothing new. Note that
>> _arguments only lets you start options with - or + and we check for
>> those explicitly in a few places. I think it's worth optimising this
>> away. The check could perhaps be factored into ca_get_opt() and
>> ca_get_sopt() ?
>>
>> If someone has a moment, please check that the calculation in
>> single_index() makes sense. The array is allocated as
>> ret->single = (Caopt *) zalloc(188 * sizeof(Caopt));
>>
>> Oliver
>>
>> diff --git a/Src/Zle/computil.c b/Src/Zle/computil.c
>> index c49d688c8..59abb4cc4 100644
>> --- a/Src/Zle/computil.c
>> +++ b/Src/Zle/computil.c
>> @@ -1088,10 +1088,10 @@ bslashcolon(char *s)
>> static int
>> single_index(char pre, char opt)
>> {
>> - if (opt <= 20 || opt > 0x7e)
>> + if (opt <= 0x20 || opt > 0x7e)
>> return -1;
>>
>> - return opt + (pre == '-' ? -21 : 94 - 21);
>> + return opt + (pre == '-' ? -0x21 : 94 - 0x21);
>> }
>>
>> /* Parse an argument definition. */
>> @@ -2158,7 +2158,8 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
>>
>> /* See if it's an option. */
>>
>> - if (state.opt == 2 && (state.curopt = ca_get_opt(d, line, 0, &pe)) &&
>> + if (state.opt == 2 && (*line == '-' || *line == '+') &&
>> + (state.curopt = ca_get_opt(d, line, 0, &pe)) &&
>> (state.curopt->type == CAO_OEQUAL ?
>> (compwords[cur] || pe[-1] == '=') :
>> (state.curopt->type == CAO_EQUAL ?
>> @@ -2206,6 +2207,7 @@ ca_parse_line(Cadef d, Cadef all, int multi, int first)
>> state.curopt = NULL;
>> }
>> } else if (state.opt == 2 && d->single &&
>> + (*line == '-' || *line == '+') &&
>> ((state.curopt = ca_get_sopt(d, line, &pe, &sopts)) ||
>> (cur != compcurrent && sopts && nonempty(sopts)))) {
>> /* Or maybe it's a single-letter option? */
Messages sorted by:
Reverse Date,
Date,
Thread,
Author