diff options
| author | Justin M. Keyes <justinkz@gmail.com> | 2026-08-16 10:24:24 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2026-08-16 10:24:24 -0400 |
| commit | 214bcf24cc7d70d8fd8fc7f172251abe4bd5ed35 (patch) | |
| tree | f6be61d73ae7cf4fda982dcb0ea1411ca3ce6dfa /runtime/lua/vim/range.lua | |
| parent | 83730db6477484c773f39c8cc18c30e09dd76f4c (diff) | |
| download | rneovim-214bcf24cc7d70d8fd8fc7f172251abe4bd5ed35.tar.gz rneovim-214bcf24cc7d70d8fd8fc7f172251abe4bd5ed35.tar.bz2 rneovim-214bcf24cc7d70d8fd8fc7f172251abe4bd5ed35.zip | |
fix(undo): crash on corrupted undo file #41339
Problem:
`:rundo` on a corrupted undo file crashes or hangs, instead of failing
with E825. Patching one 4-byte field is enough:
ue_size = 0xFFFFFFFF " walks a NULL ue_array
ue_size = 0x7FFFFFF0 " 17 GB xmalloc + memset, then preserve_exit()
ue_top = 0xFFFFFFFB " negative lnum reaches ml_delete()
Analysis:
Every count in the file is read with `undo_read_4c()` and then checked,
differently at each site. None bounds the value by what the file can
hold, so a 2 GB count reaches `xmalloc()`.
Note:
- Vim doesn't have `bi_fsize` because it checks `U_ALLOC_LINE` result
everywhere (thus doesn't crash, but may thrash...); those checks were
dropped when Nvim moved to `xmalloc()`, and the `ue_size` loop counter
became unsigned.
- Vim *does* have the negative line numbers bug: `u_undoredo()` checks
`top > ml_line_count || top >= bot || bot > ml_line_count + 1`, which
rejects none of them.
Solution:
- Introduce `undo_read_len()` and use it to fail early instead of
continuing with nonsense.
- Validate `ue_top`/`ue_bot`/ `ue_lcount`.
- Use `xcalloc()`, so no site can proceed with a NULL array.
- Report a truncated "U" line, distinguish EOF from a 0xFFFFFFFF field,
and free the header on the extmark error path.
Diffstat (limited to 'runtime/lua/vim/range.lua')
0 files changed, 0 insertions, 0 deletions