aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Duerr <chrisduerr@users.noreply.github.com>2018-07-02 22:03:04 +0000
committerGitHub <noreply@github.com>2018-07-02 22:03:04 +0000
commit07aaf05f7463a971e56de87e3b6b24e4153e5a98 (patch)
treeec94bbba133022a80a8db0336557915ba5d7f8fc
parentbfd62ef45bedf02a4f61c08bba134a2eb06c0b47 (diff)
downloadalacritty-07aaf05f7463a971e56de87e3b6b24e4153e5a98.tar.gz
alacritty-07aaf05f7463a971e56de87e3b6b24e4153e5a98.zip
Fix scrollback accessing indices out of bounds
There have been two instances of the scrollback trying to access indices which were moved out of bounds due to new lines (`yes` command). These have both been fixed. The first instance was during semantic selection, since the logic of limiting the selection start point was moved outside of `compute_index`, it was necessary to add this to semantic selection too. Now semantic selection, line selection and normal selection should all work without crashing when new lines are shoving the selection out of bounds. The other error was with the viewport being outside of the scrollback history. Since the default is to keep the scrollback buffer at its current position when new lines are added, it is possible that the position the scrollback buffer is at is suddenly shoved out of the visible area. To fix this the `display_offset` is now limited to always be an allowed value. If a single line of the viewport is moved out of the history now, the viewport should move down a single line now, so only valid content is displayed, with multiple lines this process is repeated. This fixes #1400. There was another error where the iterator would attempt to iterate before the first line in the history buffer, this was because the bounds of the `prev` iterator weren't setup correctly. The iterator should now properly iterate from the first cell in the terminal until the last one. This also fixes #1406, since these semantic selection errors were partiall related to indexing.
-rw-r--r--src/grid/mod.rs17
-rw-r--r--src/grid/storage.rs2
-rw-r--r--src/term/mod.rs8
3 files changed, 14 insertions, 13 deletions
diff --git a/src/grid/mod.rs b/src/grid/mod.rs
index 535f6cc6..949a5ed5 100644
--- a/src/grid/mod.rs
+++ b/src/grid/mod.rs
@@ -100,12 +100,6 @@ pub struct GridIterator<'a, T: 'a> {
/// Current position of the iterator within the grid.
pub cur: Point<usize>,
-
- /// Bottom of screen (buffer)
- bot: usize,
-
- /// Top of screen (buffer)
- top: usize,
}
pub enum Scroll {
@@ -357,7 +351,10 @@ impl<T: Copy + Clone> Grid<T> {
if region.start == Line(0) {
// Update display offset when not pinned to active area
if self.display_offset != 0 {
- self.display_offset += *positions;
+ self.display_offset = min(
+ self.display_offset + *positions,
+ self.len() - self.num_lines().0,
+ );
}
self.increase_scroll_limit(*positions);
@@ -433,8 +430,6 @@ impl<T> Grid<T> {
GridIterator {
grid: self,
cur: point,
- bot: self.display_offset,
- top: self.display_offset + *self.num_lines() - 1,
}
}
@@ -459,7 +454,7 @@ impl<'a, T> Iterator for GridIterator<'a, T> {
fn next(&mut self) -> Option<Self::Item> {
let last_col = self.grid.num_cols() - Column(1);
match self.cur {
- Point { line, col } if (line == self.bot) && (col == last_col) => None,
+ Point { line, col } if line == 0 && col == last_col => None,
Point { col, .. } if
(col == last_col) => {
self.cur.line -= 1;
@@ -479,7 +474,7 @@ impl<'a, T> BidirectionalIterator for GridIterator<'a, T> {
let num_cols = self.grid.num_cols();
match self.cur {
- Point { line, col: Column(0) } if line == self.top => None,
+ Point { line, col: Column(0) } if line == self.grid.len() - 1 => None,
Point { col: Column(0), .. } => {
self.cur.line += 1;
self.cur.col = num_cols - Column(1);
diff --git a/src/grid/storage.rs b/src/grid/storage.rs
index 2f34b3f0..5d6cb936 100644
--- a/src/grid/storage.rs
+++ b/src/grid/storage.rs
@@ -198,7 +198,7 @@ impl<T> Storage<T> {
/// Compute actual index in underlying storage given the requested index.
fn compute_index(&self, requested: usize) -> usize {
- debug_assert!(requested < self.inner.len());
+ debug_assert!(requested < self.len);
let zeroed = requested + self.zero;
// This part is critical for performance,
diff --git a/src/term/mod.rs b/src/term/mod.rs
index 6de8afac..67d34be1 100644
--- a/src/term/mod.rs
+++ b/src/term/mod.rs
@@ -38,6 +38,9 @@ use self::cell::LineLength;
impl selection::SemanticSearch for Term {
fn semantic_search_left(&self, mut point: Point<usize>) -> Point<usize> {
+ // Limit the starting point to the last line in the history
+ point.line = min(point.line, self.grid.len() - 1);
+
let mut iter = self.grid.iter_from(point);
let last_col = self.grid.num_cols() - Column(1);
@@ -57,6 +60,9 @@ impl selection::SemanticSearch for Term {
}
fn semantic_search_right(&self, mut point: Point<usize>) -> Point<usize> {
+ // Limit the starting point to the last line in the history
+ point.line = min(point.line, self.grid.len() - 1);
+
let mut iter = self.grid.iter_from(point);
let last_col = self.grid.num_cols() - Column(1);
@@ -1017,7 +1023,7 @@ impl Term {
}
// Starting line
- res.append(&self.grid, start.line, Column(0)..(start.col + 1));
+ res.append(&self.grid, start.line, Column(0)..start.col);
}
}