From 31e1f49cb6a43f2e439992a591a06e63e5356e74 Mon Sep 17 00:00:00 2001 From: Solomon Date: Sat, 8 Feb 2025 17:57:28 -0700 Subject: [PATCH] fix ranges over zero-length input (#15062) Fixes #15061 # User-Facing Changes Fixes panics when slicing empty input with inclusive ranges: ```nushell > random binary 0 | bytes at 0..0 Error: x Main thread panicked. |-> at crates/nu-protocol/src/value/range.rs:118:42 `-> attempt to subtract with overflow ``` --- crates/nu-command/tests/commands/str_/mod.rs | 7 +++++++ crates/nu-protocol/src/value/range.rs | 3 ++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/crates/nu-command/tests/commands/str_/mod.rs b/crates/nu-command/tests/commands/str_/mod.rs index 2aeabfd04a..9a361f7d43 100644 --- a/crates/nu-command/tests/commands/str_/mod.rs +++ b/crates/nu-command/tests/commands/str_/mod.rs @@ -388,6 +388,13 @@ fn substring_by_negative_index() { }) } +#[test] +fn substring_of_empty_string() { + let actual = nu!("'' | str substring ..0"); + assert_eq!(actual.err, ""); + assert_eq!(actual.out, ""); +} + #[test] fn str_reverse() { let actual = nu!(r#" diff --git a/crates/nu-protocol/src/value/range.rs b/crates/nu-protocol/src/value/range.rs index 9ce9c6fa54..5524a79fe3 100644 --- a/crates/nu-protocol/src/value/range.rs +++ b/crates/nu-protocol/src/value/range.rs @@ -112,8 +112,9 @@ mod int_range { match self.end { Bound::Unbounded => Bound::Unbounded, Bound::Included(i) => match i { + _ if len == 0 => Bound::Excluded(0), i if i < 0 => Bound::Excluded(len.saturating_sub((i + 1).unsigned_abs())), - i => Bound::Included((len - 1).min(i.unsigned_abs())), + i => Bound::Included((len.saturating_sub(1)).min(i.unsigned_abs())), }, Bound::Excluded(i) => Bound::Excluded(match i { i if i < 0 => len.saturating_sub(i.unsigned_abs()),