CVE-2026-52859
Description
An out-of-bounds read in Vim's update_snapshot() function can be triggered by a terminal program outputting a cell with six characters, causing a crash.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
An out-of-bounds read in Vim's update_snapshot() function can be triggered by a terminal program outputting a cell with six characters, causing a crash.
Vulnerability
In Vim versions prior to 9.2.0565, the update_snapshot() function in src/terminal.c copies the visible terminal screen into the scrollback buffer. For each screen cell, it iterates over the chars[] array without an upper bound, stopping only at a NUL terminator. When a cell contains exactly VTERM_MAX_CHARS_PER_CELL (6) characters (base plus five combining marks), the bundled libvterm returns the array without a terminating NUL, causing the loop to read past the array boundary. This leads to an out-of-bounds read [1].
Exploitation
An attacker who can control the output displayed inside a Vim :terminal window can trigger this vulnerability by emitting a single cell that fills all six character slots. No Vim scripting or user interaction beyond viewing the terminal output is required. The program running in the terminal only needs to output a short byte sequence that results in a base character with five combining marks [1].
Impact
The out-of-bounds read causes Vim to read memory beyond the chars[] array and append those values to the snapshot buffer, which was allocated for only six characters. This can lead to a crash (denial of service). The advisory notes that the program inside the terminal normally cannot affect the parent Vim process's memory, but this bug allows a crash [1].
Mitigation
The issue has been patched in Vim version 9.2.0565, released on 30 May 2026. Users should update to this version or later. No workarounds are mentioned in the available references [1][2][3].
AI Insight generated on Jun 11, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
163680c6d3d52patch 9.2.0565: [security]: out-of-bounds read in update_snapshot()
4 files changed · +219 −1
src/terminal.c+2 −1 modified@@ -2265,7 +2265,8 @@ update_snapshot(term_T *term) int i; int c; - for (i = 0; (c = cell.chars[i]) > 0 || i == 0; ++i) + for (i = 0; i < VTERM_MAX_CHARS_PER_CELL && + ((c = cell.chars[i]) > 0 || i == 0); ++i) ga.ga_len += utf_char2bytes(c == NUL ? ' ' : c, (char_u *)ga.ga_data + ga.ga_len); }
src/testdir/samples/combining_chars.txt+200 −0 added@@ -0,0 +1,200 @@ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ +á́́́́ጁ
src/testdir/test_terminal3.vim+15 −0 modified@@ -1241,4 +1241,19 @@ func Test_terminal_csi_args_overflow() call StopVimInTerminal(buf) endfunc +func Test_terminal_output_combining_chars() + CheckUnix + new + let cmd = "cat samples/combining_chars.txt" + let buf = term_start(cmd, {'curwin': 1, 'term_finish': 'open', 'term_rows': 10, 'term_cols': 30}) + call WaitForAssert({-> assert_match('finished', term_getstatus(buf))}) + call TermWait(buf) + let lines = getbufline(buf, 1, '$') + " get byte lengths to confirm combining chars present + let lens = map(copy(lines), 'len(v:val)') + let expected = repeat([11], 190) + repeat([14], 10) + call assert_equal(expected, lens) + bw! +endfunc + " vim: shiftwidth=2 sts=2 expandtab
src/version.c+2 −0 modified@@ -729,6 +729,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 565, /**/ 564, /**/
Vulnerability mechanics
Root cause
"Missing upper-bound check in the loop over cell.chars[] in update_snapshot() causes an out-of-bounds read when libvterm returns a full array without a NUL terminator."
Attack vector
An attacker who can control output displayed inside a Vim `:terminal` window can craft a single terminal cell containing a base character plus five combining marks, filling all six `VTERM_MAX_CHARS_PER_CELL` slots. Because libvterm does not NUL-terminate a full array, `update_snapshot()` reads past the fixed-size buffer and appends out-of-bounds values to the snapshot buffer, causing a crash. No Vim scripting or user interaction beyond viewing the terminal output is required [ref_id=1].
Affected code
The vulnerable function is `update_snapshot()` in `src/terminal.c`. The loop iterating over `cell.chars[]` lacks an upper bound check, relying solely on a NUL terminator that libvterm omits when all six slots are filled. The patch adds the guard `i < VTERM_MAX_CHARS_PER_CELL` to the loop condition.
What the fix does
The patch adds `i < VTERM_MAX_CHARS_PER_CELL` to the loop condition in `update_snapshot()`, ensuring the loop never reads beyond the six-element `cell.chars[]` array even when libvterm omits the NUL terminator. This mirrors the existing safe loop in `handle_pushline()`. A test file (`samples/combining_chars.txt`) containing cells with five combining marks and a Vim test function (`Test_terminal_output_combining_chars`) were added to verify the fix [patch_id=5620673].
Preconditions
- inputThe attacker must be able to produce terminal output that is rendered inside a Vim :terminal window.
- inputThe terminal cell must contain a base character plus five combining marks, filling all VTERM_MAX_CHARS_PER_CELL slots.
- configThe update_snapshot() function must be triggered, e.g., by entering Terminal-Normal mode (CTRL-W N) or when the terminal job exits.
Generated on Jun 11, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.