From e84d1109954b3890a340edc4cb49b25db664a6a1 Mon Sep 17 00:00:00 2001 From: Johannes Altmanninger Date: Tue, 9 Jan 2024 18:11:14 +0100 Subject: [PATCH] Fix arithmetic overflow in up-line The C++ code implicitly relied on wrapping behavior. There are probably more cases like this. Maybe we should disable "overflow-checks" in release mode. --- fish-rust/src/parse_util.rs | 3 ++- fish-rust/src/reader.rs | 7 ++++--- tests/checks/tmux-bind.fish | 10 ++++++++++ 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/fish-rust/src/parse_util.rs b/fish-rust/src/parse_util.rs index 586baf444..5b4758b8f 100644 --- a/fish-rust/src/parse_util.rs +++ b/fish-rust/src/parse_util.rs @@ -528,10 +528,11 @@ pub fn parse_util_get_offset_from_line(s: &wstr, line: i32) -> Option { } /// Return the total offset of the buffer for the cursor position nearest to the specified position. -pub fn parse_util_get_offset(s: &wstr, line: i32, mut line_offset: usize) -> Option { +pub fn parse_util_get_offset(s: &wstr, line: i32, line_offset: isize) -> Option { let off = parse_util_get_offset_from_line(s, line)?; let off2 = parse_util_get_offset_from_line(s, line + 1).unwrap_or(s.len() + 1); + let mut line_offset = line_offset as usize; if line_offset >= off2 - off - 1 { line_offset = off2 - off - 1; } diff --git a/fish-rust/src/reader.rs b/fish-rust/src/reader.rs index 1e229568d..b1bc77e6c 100644 --- a/fish-rust/src/reader.rs +++ b/fish-rust/src/reader.rs @@ -2648,10 +2648,11 @@ impl ReaderData { let indent_old = indents[std::cmp::min(indents.len() - 1, base_pos_old)]; let indent_new = indents[std::cmp::min(indents.len() - 1, base_pos_new)]; - let indent_old = usize::try_from(indent_old).unwrap(); - let indent_new = usize::try_from(indent_new).unwrap(); + let indent_old = isize::try_from(indent_old).unwrap(); + let indent_new = isize::try_from(indent_new).unwrap(); - let line_offset_old = el.position() - base_pos_old; + let line_offset_old = + isize::try_from(el.position() - base_pos_old).unwrap(); let total_offset_new = parse_util_get_offset( el.text(), line_new, diff --git a/tests/checks/tmux-bind.fish b/tests/checks/tmux-bind.fish index e10a82681..1cb412954 100644 --- a/tests/checks/tmux-bind.fish +++ b/tests/checks/tmux-bind.fish @@ -9,3 +9,13 @@ tmux-sleep isolated-tmux capture-pane -p # CHECK: prompt 0> echo 12345 # CHECK: echo abcde + +isolated-tmux send-keys C-c +tmux-sleep +isolated-tmux send-keys C-l +isolated-tmux send-keys begin Enter 'echo 1' Enter e n d C-p 23 +tmux-sleep +isolated-tmux capture-pane -p +# CHECK: prompt 0> begin +# CHECK: echo 123 +# CHECK: end