summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichael Brumlow <mbrumlow@gmail.com>2017-01-10 00:05:26 -0600
committerMichael Brumlow <mbrumlow@gmail.com>2017-01-10 00:57:49 -0600
commitb99fda521447e38b4ca800d20e93e3bd2250517f (patch)
treedda3fd4d66c63d5c894ce4337838b94123f1a7d1 /src
parentff5156040eb7bc02b57aa8a25724c9cafab9b586 (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.rs39
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));
}