Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: PATCH: zle: various issues



On Thu, May 14, 2026 at 5:20 PM Mikael Magnusson <mikachu@xxxxxxxxx> 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




Messages sorted by: Reverse Date, Date, Thread, Author