From c28ec4c3504c9e2ffab34a4e599250034dc4fdbf Mon Sep 17 00:00:00 2001 From: Anton Bolshakov Date: Tue, 21 Jul 2026 15:21:05 +0800 Subject: [PATCH] selection_extract: clamp row index before grid access sel_start_row/sel_end_row can legitimately exceed MAX_ROWS-1 during scrollback selection (incremented in lockstep with scroll_offset so the .se_row_grid_shifted path keeps them in bounds). If scroll_offset is reset to 0 before a SelectionRequest arrives (e.g. the user drags selected text to another window after the viewport snapped back), the .se_row_live path fires instead and computes grid + r12 * MAX_COLS * CELL_SIZE with r12 >= MAX_ROWS, producing an out-of-bounds read and segfault. Add a MAX_ROWS guard in both .se_row_live and .se_row_grid_shifted before the imul/lea sequence. An out-of-range row jumps to .se_done, truncating the selection at the valid region rather than crashing. Fixes: https://github.com/isene/glass/issues/2 Co-Authored-By: Claude Sonnet 4.6 --- glass.asm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/glass.asm b/glass.asm index f94e546..1371dc7 100644 --- a/glass.asm +++ b/glass.asm @@ -11611,12 +11611,16 @@ selection_extract: .se_row_grid_shifted: mov rax, r12 sub rax, [scroll_offset] + cmp rax, MAX_ROWS ; guard: shifted row must be in [0, MAX_ROWS) + jge .se_done imul rax, MAX_COLS imul rax, CELL_SIZE lea rbx, [grid + rax] jmp .se_row_base_done .se_row_live: mov rax, r12 + cmp rax, MAX_ROWS ; guard: row must be in [0, MAX_ROWS) + jge .se_done imul rax, MAX_COLS imul rax, CELL_SIZE lea rbx, [grid + rax]