From cc08dc071075e264ce9f1795380ef87991db9754 Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Thu, 16 Jan 2025 08:59:22 -0500 Subject: [PATCH] Fix slicing panic in path completion variable expansion The regexes in `expand_impl` may match multiple times on a single variable like `${HOME:-$HOME}`: once for the `${HOME:-` part and again for its default value `$HOME`. This could cause a panic because of an invalid slice `&bytes[pos..range.start]`: `pos` is set to `range.end` which corresponds to the closing `}` in the first iteration of the loop, so it's greater than `range.start` in the second iteration. --- helix-stdx/src/env.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/helix-stdx/src/env.rs b/helix-stdx/src/env.rs index 6e14c7a875ae9..bef2976895032 100644 --- a/helix-stdx/src/env.rs +++ b/helix-stdx/src/env.rs @@ -103,6 +103,12 @@ fn expand_impl(src: &OsStr, mut resolve: impl FnMut(&OsStr) -> Option) let mat = captures.get_match().unwrap(); let pattern_id = mat.pattern().as_usize(); let mut range = mat.range(); + // A pattern may match multiple times on a single variable, for example `${HOME:-$HOME}`: + // `${HOME:-` matches and also the default value (`$HOME`). Skip past any variables which + // have already been expanded. + if range.start < pos { + continue; + } let var = &bytes[captures.get_group(1).unwrap().range()]; let default = if pattern_id != 5 { let Some(bracket_pos) = find_brace_end(&bytes[range.end..]) else {