From f10b43651b06b250abd65570b491cfa03d21f206 Mon Sep 17 00:00:00 2001
From: "gcp-cherry-pick-bot[bot]"
<98988430+gcp-cherry-pick-bot[bot]@users.noreply.github.com>
Date: Mon, 27 Jan 2025 17:18:08 +0200
Subject: [PATCH] Avoid panics when normalizing completion label with invalid
ranges (cherry-pick #23712) (#23718)
Cherry-picked Avoid panics when normalizing completion label with
invalid ranges (#23712)
Dev builds show panics related to completion label normalization
Panic
```
index out of bounds: the len is 103 but the index is 103
zed::reliability::init_panic_hook::{{closure}}::h78130eff43c84f6f+110375521
std::panicking::rust_panic_with_hook::hfe205f6954b2c97b+87457752
std::panicking::begin_panic_handler::{{closure}}::h6cb44b3a50f28c44+87456967
std::sys::backtrace::__rust_end_short_backtrace::hf1c1f2a92799bb0e+87449337
rust_begin_unwind+87456084
core::panicking::panic_fmt::h3d8fc78294164da7+7033011
core::panicking::panic_bounds_check::h9397cb495d89a72d+7033511
project::lsp_store::ensure_uniform_list_compatible_label::haf80316ce11edd67+72663592
project::lsp_store::populate_labels_for_completions::{{closure}}::hc93c3c540ef7d2d6+72642960
project::lsp_store::LspStore::completions::{{closure}}::{{closure}}::hb4b5432e24432ca8+72336627
async_task::raw::RawTask::run::hf444c3dc07dd583b+68504803
::run::hbf5a316eb781a10d+50646579
gpui::platform::linux::platform::::run::hc85518d4552fc4cd+50496669
gpui::app::App::run::hca4e2eaf984ca6f6+109905269
zed::main::h849467ac1a6d32c9+110413414
std::sys::backtrace::__rust_begin_short_backtrace::h81b5ee155a7cf505+110835475
std::rt::lang_start::{{closure}}::h48a83f884cfb6865+110834761
std::rt::lang_start_internal::h5e7c81cecd7f0954+87382485
main+110425932
__libc_start_call_main+22789462491720
__libc_start_main_alias_1+22789462491915
_start+10436606
```
This can only happen when either `label.runs` or `label.filter_range`
has a range that's larger than the label text, which is an error.
Instead of panicking, log such errors and fall back to last index (which
is not really helpful, but still).
Release Notes:
- N/A
Co-authored-by: Kirill Bulatov
---
crates/project/src/lsp_store.rs | 53 +++++++++++++++++++++++++++++----
1 file changed, 48 insertions(+), 5 deletions(-)
diff --git a/crates/project/src/lsp_store.rs b/crates/project/src/lsp_store.rs
index 5bdee5cb5cb83a06577ad6ca6d330fc3b95ad958..b8f0d90c8cff9f1bc0c351364056a43c8acdf0a7 100644
--- a/crates/project/src/lsp_store.rs
+++ b/crates/project/src/lsp_store.rs
@@ -8786,16 +8786,59 @@ fn ensure_uniform_list_compatible_label(label: &mut CodeLabel) {
return;
}
- for (range, _) in &mut label.runs {
- range.start = offset_map[range.start];
- range.end = offset_map[range.end];
+ let last_index = new_idx;
+ let mut run_ranges_errors = Vec::new();
+ label.runs.retain_mut(|(range, _)| {
+ match offset_map.get(range.start) {
+ Some(&start) => range.start = start,
+ None => {
+ run_ranges_errors.push(range.clone());
+ return false;
+ }
+ }
+
+ match offset_map.get(range.end) {
+ Some(&end) => range.end = end,
+ None => {
+ run_ranges_errors.push(range.clone());
+ range.end = last_index;
+ }
+ }
+ true
+ });
+ if !run_ranges_errors.is_empty() {
+ log::error!(
+ "Completion label has errors in its run ranges: {run_ranges_errors:?}, label text: {}",
+ label.text
+ );
}
+ let mut wrong_filter_range = None;
if label.filter_range == (0..label.text.len()) {
label.filter_range = 0..new_text.len();
} else {
- label.filter_range.start = offset_map[label.filter_range.start];
- label.filter_range.end = offset_map[label.filter_range.end];
+ let mut original_filter_range = Some(label.filter_range.clone());
+ match offset_map.get(label.filter_range.start) {
+ Some(&start) => label.filter_range.start = start,
+ None => {
+ wrong_filter_range = original_filter_range.take();
+ label.filter_range.start = last_index;
+ }
+ }
+
+ match offset_map.get(label.filter_range.end) {
+ Some(&end) => label.filter_range.end = end,
+ None => {
+ wrong_filter_range = original_filter_range.take();
+ label.filter_range.end = last_index;
+ }
+ }
+ }
+ if let Some(wrong_filter_range) = wrong_filter_range {
+ log::error!(
+ "Completion label has an invalid filter range: {wrong_filter_range:?}, label text: {}",
+ label.text
+ );
}
label.text = new_text;