mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-10-09 03:49:27 +00:00
Fix an out of bounds memory access when drawing a multi line character with cursor below bottom margin
This commit is contained in:
parent
c9896e8c00
commit
c02f932641
3 changed files with 34 additions and 5 deletions
|
|
@ -199,6 +199,12 @@ you use a decent Wayland compositor.
|
|||
Detailed list of changes
|
||||
-------------------------------------
|
||||
|
||||
0.49.2 [future]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
- Fix an out-of-bounds memory access when drawing a multi-line text sized
|
||||
character with the cursor below the bottom margin of the scroll region
|
||||
|
||||
0.49.1 [2026-09-24]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
|
|
|||
|
|
@ -1568,11 +1568,19 @@ handle_fixed_width_multicell_command(Screen *self, CPUCell mcd, ListOfChars *lc)
|
|||
cell_set_chars(&mcd, self->text_cache, lc);
|
||||
move_cursor_past_multicell(self, width);
|
||||
if (height > 1) {
|
||||
index_type available_height = self->margin_bottom - self->cursor->y + 1;
|
||||
if (height > available_height) {
|
||||
index_type extra_lines = height - available_height;
|
||||
screen_scroll(self, extra_lines);
|
||||
self->cursor->y -= extra_lines;
|
||||
if (self->cursor->y <= self->margin_bottom) {
|
||||
index_type available_height = self->margin_bottom - self->cursor->y + 1;
|
||||
if (height > available_height) {
|
||||
index_type extra_lines = height - available_height;
|
||||
screen_scroll(self, extra_lines);
|
||||
self->cursor->y -= extra_lines;
|
||||
}
|
||||
} else {
|
||||
// Cursor is below the scroll region, which cannot be scrolled, so
|
||||
// move the cursor up until the cell fits on screen. height <=
|
||||
// max_height <= lines so this cannot underflow.
|
||||
index_type available_height = self->lines - self->cursor->y;
|
||||
if (height > available_height) self->cursor->y -= height - available_height;
|
||||
}
|
||||
}
|
||||
if (self->modes.mIRM) {
|
||||
|
|
|
|||
|
|
@ -25,6 +25,21 @@ class TestMulticell(BaseTest):
|
|||
s.draw('好好') # two 2-cell wide chars covering columns 0..3
|
||||
s.test_draw_overlay_line('xy', xstart, 0) # would SIGSEGV without fix
|
||||
|
||||
def test_multicell_below_bottom_margin(self):
|
||||
# Regression: with the cursor below the bottom margin, the available
|
||||
# height computation underflowed and cells were written past the end
|
||||
# of the line buffer.
|
||||
s = self.create_screen(cols=10, lines=6)
|
||||
s.set_margins(1, 3) # 1-based indexing
|
||||
s.cursor.x, s.cursor.y = 0, s.lines - 1
|
||||
multicell(s, 'A', scale=2)
|
||||
self.ae((s.cursor.x, s.cursor.y), (2, s.lines - 2))
|
||||
for y in (s.lines - 2, s.lines - 1):
|
||||
for x in range(2):
|
||||
c = s.cpu_cells(y, x)
|
||||
self.assertIsNotNone(c['mcd'])
|
||||
self.ae((c['x'], c['y'], c['mcd']['scale']), (x, y - s.lines + 2, 2))
|
||||
|
||||
|
||||
def test_multicell(self: TestMulticell) -> None:
|
||||
from kitty.tab_bar import as_rgb
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue