fix(terminal): prevent escaping pane through scroll region (#3491)

This commit is contained in:
Aram Drevekenin 2024-07-12 12:22:44 +02:00 committed by GitHub
parent 5b3a9b5dad
commit f9ded24b21
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 88 additions and 1 deletions

View file

@ -2745,7 +2745,9 @@ impl Perform for Grid {
.next() .next()
.map(|param| param[0] as usize) .map(|param| param[0] as usize)
.filter(|&param| param != 0) .filter(|&param| param != 0)
.map(|bottom| bottom.saturating_sub(1)); .map(|bottom| {
std::cmp::min(self.height.saturating_sub(1), bottom.saturating_sub(1))
});
self.set_scroll_region(top, bottom); self.set_scroll_region(top, bottom);
if self.erasure_mode { if self.erasure_mode {
self.move_cursor_to_line(top, EMPTY_TERMINAL_CHARACTER); self.move_cursor_to_line(top, EMPTY_TERMINAL_CHARACTER);

View file

@ -3862,3 +3862,41 @@ fn text_ui_component_with_coordinates() {
} }
assert_snapshot!(format!("{:?}", grid)); assert_snapshot!(format!("{:?}", grid));
} }
#[test]
fn cannot_escape_scroll_region() {
// this tests a fix for a bug where it would be possible to set the scroll region bounds beyond
// the pane height, which would then allow a goto instruction beyond the scroll region to scape
// the pane bounds and render content on other panes
//
// what we do here is set the scroll region beyond the terminal bounds (`<ESC>[1;42r` - whereas
// the terminal is just 41 lines high), and then issue a goto instruction to line 42, one line
// beyond the pane and scroll region bounds (`<ESC>[42;1H`) and then print text `Hi there!`.
// This should be printed on the last line (zero indexed 40) of the terminal and not beyond it.
let mut vte_parser = vte::Parser::new();
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
let debug = false;
let arrow_fonts = true;
let styled_underlines = true;
let explicitly_disable_kitty_keyboard_protocol = false;
let mut grid = Grid::new(
41,
120,
Rc::new(RefCell::new(Palette::default())),
terminal_emulator_color_codes,
Rc::new(RefCell::new(LinkHandler::new())),
Rc::new(RefCell::new(None)),
sixel_image_store,
Style::default(),
debug,
arrow_fonts,
styled_underlines,
explicitly_disable_kitty_keyboard_protocol,
);
let content = "\u{1b}[1;42r\u{1b}[42;1HHi there!".as_bytes();
for byte in content {
vte_parser.advance(&mut grid, *byte);
}
assert_snapshot!(format!("{:?}", grid));
}

View file

@ -0,0 +1,47 @@
---
source: zellij-server/src/panes/./unit/grid_tests.rs
assertion_line: 3894
expression: "format!(\"{:?}\", grid)"
---
00 (C):
01 (C):
02 (C):
03 (C):
04 (C):
05 (C):
06 (C):
07 (C):
08 (C):
09 (C):
10 (C):
11 (C):
12 (C):
13 (C):
14 (C):
15 (C):
16 (C):
17 (C):
18 (C):
19 (C):
20 (C):
21 (C):
22 (C):
23 (C):
24 (C):
25 (C):
26 (C):
27 (C):
28 (C):
29 (C):
30 (C):
31 (C):
32 (C):
33 (C):
34 (C):
35 (C):
36 (C):
37 (C):
38 (C):
39 (C):
40 (C): Hi there!