neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

commit 34be915f6b9313d7554aa973a82277504de4e285
parent 40bfca744dd0c87df6ec2ab776f982636e4b0904
Author: L Lllvvuu <git@llllvvuu.dev>
Date:   Sat, 16 Sep 2023 01:08:06 -0700

fix(marktree): preserve ordering in `marktree_move`

`marktree_move` is making the tree out of order at:

https://github.com/neovim/neovim/blob/be10d65bfafe056025ffffa2c1131712b9a493a5/src/nvim/marktree.c#L1188

Because `key` is at the new position, and `x->key[new_i]` is also at the
new position, this comparison spuriously returns true, which causes
`x->key[i]` to be updated in-place even when it needs to be moved.

This causes crashes down the line, since the ordering of `MTNode.key` is
an invariant that must be preserved.

Fixes: #25157

Diffstat:
Msrc/nvim/marktree.c | 5++++-
1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/nvim/marktree.c b/src/nvim/marktree.c @@ -1178,6 +1178,9 @@ void marktree_move(MarkTree *b, MarkTreeIter *itr, int row, int col) } if (internal) { + if (key.pos.row == newpos.row && key.pos.col == newpos.col) { + return; + } key.pos = newpos; bool match; // tricky: could minimize movement in either direction better @@ -1185,7 +1188,7 @@ void marktree_move(MarkTree *b, MarkTreeIter *itr, int row, int col) if (!match) { new_i++; } - if (new_i == itr->i || key_cmp(key, x->key[new_i]) == 0) { + if (new_i == itr->i) { x->key[itr->i].pos = newpos; } else if (new_i < itr->i) { memmove(&x->key[new_i + 1], &x->key[new_i], sizeof(MTKey) * (size_t)(itr->i - new_i));