summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2024-07-12 11:49:30 +0200
committerAram Drevekenin <aram@poor.dev>2024-07-12 11:49:30 +0200
commit8d16c5bbcd98b62b18bcb7b74f68a89306811e0c (patch)
tree71422697ce72e8c8af0308f846ce0c1617d5d774
parent5b3a9b5dad481120bf9a09e916f9e5421c6c3fa4 (diff)
fix(terminal): prevent escaping pane through scroll regionfix-scroll-region-escape
-rw-r--r--zellij-server/src/panes/grid.rs4
-rw-r--r--zellij-server/src/panes/unit/grid_tests.rs38
-rw-r--r--zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__cannot_escape_scroll_region.snap47
3 files changed, 88 insertions, 1 deletions
diff --git a/zellij-server/src/panes/grid.rs b/zellij-server/src/panes/grid.rs
index c22cb4808..781030b17 100644
--- a/zellij-server/src/panes/grid.rs
+++ b/zellij-server/src/panes/grid.rs
@@ -2745,7 +2745,9 @@ impl Perform for Grid {
.next()
.map(|param| param[0] as usize)
.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);
if self.erasure_mode {
self.move_cursor_to_line(top, EMPTY_TERMINAL_CHARACTER);
diff --git a/zellij-server/src/panes/unit/grid_tests.rs b/zellij-server/src/panes/unit/grid_tests.rs
index 4b8b10c2d..21c17b9ef 100644
--- a/zellij-server/src/panes/unit/grid_tests.rs
+++ b/zellij-server/src/panes/unit/grid_tests.rs
@@ -3862,3 +3862,41 @@ fn text_ui_component_with_coordinates() {
}
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));
+}
diff --git a/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__cannot_escape_scroll_region.snap b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__cannot_escape_scroll_region.snap
new file mode 100644
index 000000000..b2dcaaa79
--- /dev/null
+++ b/zellij-server/src/panes/unit/snapshots/zellij_server__panes__grid__grid_tests__cannot_escape_scroll_region.snap
@@ -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!
+