diff options
author | Christian Duerr <contact@christianduerr.com> | 2021-07-22 22:11:12 +0000 |
---|---|---|
committer | Christian Duerr <contact@christianduerr.com> | 2021-07-24 21:29:07 +0000 |
commit | c7678fc0eb06ae6cde6733e8e92660c4ec1120f7 (patch) | |
tree | d5c50d7c8033b31c24e81575561a52971e04b9fd | |
parent | b085fbaca3290edf0497fb1f5313b86a89ca1ce1 (diff) | |
download | alacritty-c7678fc0eb06ae6cde6733e8e92660c4ec1120f7.tar.gz alacritty-c7678fc0eb06ae6cde6733e8e92660c4ec1120f7.zip |
Fix insert mode crash with fullwidth characters
This patch resolves an issue with fullwidth characters, where it is
possible to crash Alacritty by moving a fullwidth character off the side
of the terminal using insert mode.
This issue occurs since trying to overwrite a fullwidth spacer in the
first column leads to an underflow when trying to access its fullwidth
character cell. During insert mode before the character is inserted into
the cell, the existing content is rotated to the right, which leads to
the fullwidth spacer being in the first column even though it is only
there temporarily to be immediately overwritten.
While it would be possible to clear the flags after rotation, this would
still leave the opportunity for other ways to trigger this issue and
cause a separate crash. So instead the column is checked while
overwriting the spacer to make sure the fullwidth character isn't
accessed if it would lead to an underflow.
The following is a minimal example for reproducing this crash:
```sh
printf "漢"
printf "\e[4h"
printf "\r"
for _ in $(seq 3 $(tput cols)); do
printf "x"
done
printf "\r_"
```
Fixes #5337.
-rw-r--r-- | alacritty_terminal/src/term/mod.rs | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/alacritty_terminal/src/term/mod.rs b/alacritty_terminal/src/term/mod.rs index b560d69e..8013f6c5 100644 --- a/alacritty_terminal/src/term/mod.rs +++ b/alacritty_terminal/src/term/mod.rs @@ -792,9 +792,9 @@ impl<T> Term<T> { // Remove wide char and spacer. let wide = cursor_cell.flags.contains(Flags::WIDE_CHAR); let point = self.grid.cursor.point; - if wide && point.column + 1 < self.columns() { + if wide && point.column <= self.last_column() { self.grid[point.line][point.column + 1].flags.remove(Flags::WIDE_CHAR_SPACER); - } else { + } else if point.column > 0 { self.grid[point.line][point.column - 1].clear_wide(); } |