diff options
author | Michael Brumlow <mbrumlow@gmail.com> | 2017-01-10 00:05:26 -0600 |
---|---|---|
committer | Michael Brumlow <mbrumlow@gmail.com> | 2017-01-10 00:57:49 -0600 |
commit | b99fda521447e38b4ca800d20e93e3bd2250517f (patch) | |
tree | dda3fd4d66c63d5c894ce4337838b94123f1a7d1 /src | |
parent | ff5156040eb7bc02b57aa8a25724c9cafab9b586 (diff) |
Fixing panic on cat /dev/urandom
- Checks to make sure lines count coming from the pty are within a proper
range before doing scrolling.
- Sanitizes scroll region when being set.
- Changes panic for unimplemented screen clear to a print statement.
The first two changes ensure scrolling won't crash us. By sanitizing the
region on set we don't have to complicate the scroll code with limits,
mins, or maxes to ensure the scroll operation is within the range.
Checking if the lines is greater than the total region allows us to
simply clear the region and avoid subtracting large numbers from small
ones.
Diffstat (limited to 'src')
-rw-r--r-- | src/term/mod.rs | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/src/term/mod.rs b/src/term/mod.rs index 47d30d3f..4cb0c815 100644 --- a/src/term/mod.rs +++ b/src/term/mod.rs @@ -567,6 +567,7 @@ impl Term { /// Scroll screen down /// /// Text moves down; clear at bottom + /// Expects origin to be in scroll range. #[inline] fn scroll_down_relative(&mut self, origin: Line, lines: Line) { debug_println!("scroll_down: {}", lines); @@ -574,18 +575,24 @@ impl Term { // Copy of cell template; can't have it borrowed when calling clear/scroll let template = self.empty_cell; + // Clear the entire region if lines is going to be greater than the region. + // This also ensures all the math below this if statement is sane. + if lines > self.scroll_region.end - origin { + self.grid.clear_region(origin..self.scroll_region.end, |c| c.reset(&template)); + return; + } + // Clear `lines` lines at bottom of area { let end = self.scroll_region.end; - let start = limit(end - lines, Line(0), self.scroll_region.end); + let start = end - lines; self.grid.clear_region(start..end, |c| c.reset(&template)); } // Scroll between origin and bottom { let end = self.scroll_region.end; - let start = limit(origin + lines, Line(0), self.scroll_region.end); - let lines = limit(lines, Line(0), self.grid.num_lines()); + let start = origin + lines; self.grid.scroll_down(start..end, lines); } } @@ -593,6 +600,7 @@ impl Term { /// Scroll screen up /// /// Text moves up; clear at top + /// Expects origin to be in scroll range. #[inline] fn scroll_up_relative(&mut self, origin: Line, lines: Line) { debug_println!("scroll_up: {}", lines); @@ -600,19 +608,23 @@ impl Term { // Copy of cell template; can't have it borrowed when calling clear/scroll let template = self.empty_cell; + // Clear the entire region if lines is going to be greater than the region. + // This also ensures all the math below this if statement is sane. + if lines > self.scroll_region.end - origin { + self.grid.clear_region(origin..self.scroll_region.end, |c| c.reset(&template)); + return; + } + // Clear `lines` lines starting from origin to origin + lines - { - let start = limit(origin, Line(0), self.grid.num_lines() - 1); - let end = limit(start + lines, Line(0), self.grid.num_lines() - 1); - self.grid.clear_region(start..end, |c| c.reset(&template)); + { + let end = origin + lines; + self.grid.clear_region(origin..end, |c| c.reset(&template)); } // Scroll from origin to bottom less number of lines { - let start = limit(origin, Line(0), self.grid.num_lines() - 1); - let end = limit(self.scroll_region.end - lines, Line(0), self.grid.num_lines() - 1); - let lines = limit(lines, Line(0), self.grid.num_lines()); - self.grid.scroll_up(start..end, lines); + let end = self.scroll_region.end - lines; + self.grid.scroll_up(origin..end, lines); } } } @@ -968,7 +980,7 @@ impl ansi::Handler for Term { self.grid.clear(|c| c.reset(&template)); }, _ => { - panic!("ansi::ClearMode::Above not implemented"); + err_println!("ansi::ClearMode::Above not implemented"); } } } @@ -1057,7 +1069,8 @@ impl ansi::Handler for Term { #[inline] fn set_scrolling_region(&mut self, region: Range<Line>) { debug_println!("set scroll region: {:?}", region); - self.scroll_region = region; + self.scroll_region.start = min(region.start, self.grid.num_lines()); + self.scroll_region.end = min(region.end, self.grid.num_lines()); self.goto(Line(0), Column(0)); } |