Re: PATCH: zle: various issues

Mikael Magnusson <[email protected]>
Newsgroups gmane.comp.shells.zsh.devel
Message-ID <CAHYJk3TC=5+4icuZ3=MO-i3ecNospZdpLTjPX=W1fUpZaUVdNg@mail.gmail.com>
On Thu, May 14, 2026 at 5:20 PM Mikael Magnusson <[email protected]> wrote:
>
> fix out of bounds access in vimatchbracket
> ==11986== Invalid read of size 4
> ==11986==    at 0x658D14C: vimatchbracket (zle_move.c:645)
>
> diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c
> index 3bafff3f10..7f46786836 100644
> @@ -642,6 +642,8 @@ vimatchbracket(UNUSED(char **args))
>             DECCS();
>         else
>             INCCS();
> +       if (zlecs < 0 && zlecs >= zlell)
> +           break;
>         if (zleline[zlecs] == oth)
>             ct--;
>         else if (zleline[zlecs] == me)

Oops.

diff --git a/Src/Zle/zle_move.c b/Src/Zle/zle_move.c
index 7f46786836..6863d14b7e 100644
--- a/Src/Zle/zle_move.c
+++ b/Src/Zle/zle_move.c
@@ -642,7 +642,7 @@ vimatchbracket(UNUSED(char **args))
            DECCS();
        else
            INCCS();
-       if (zlecs < 0 && zlecs >= zlell)
+       if (zlecs < 0 || zlecs >= zlell)
            break;
        if (zleline[zlecs] == oth)
            ct--;

Although now that I tried to reproduce this again, I got a valgrind
booboo even with this fix, because INCCS/DECCS already walk outside
the valid range:
==24835== Invalid read of size 4
==24835==    at 0x64DC039: alignmultiwordleft (zle_move.c:58)
==24835==    by 0x64DC23F: deccs (zle_move.c:136)
==24835==    by 0x64DD1BD: vimatchbracket (zle_move.c:642)
==24835==    by 0x64D445D: execzlefunc (zle_main.c:1488)

If you put a combiningchar as the first character on a line, and then
a non-matching closing bracket, and invoke vi-match-bracket (with
COMBININGCHARS enabled),
@@ -51,7 +51,7 @@ alignmultiwordleft(int *pos, int setpos)
     int loccs = *pos;

     /* generic nothing to do test */
-    if (!isset(COMBININGCHARS) || loccs == zlell || loccs == 0)
+    if (!isset(COMBININGCHARS) || loccs >= zlell || loccs <= 0)
        return 0;

     /* need to be on combining character */

We can't clamp zlecs to [0,zlell] in inccs/deccs because the loop in
vimatchbracket (and probably many other places) depend on zlecs going
out of range as the stopping condition, so they would just loop
infinitely.

-- 
Mikael Magnusson
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.