ui: Don't panic on invalid highlight indices in HighlightedLabel (#57291)
Some checks are pending
Congratsbot / check-author (push) Waiting to run
Congratsbot / congrats (push) Blocked by required conditions
run_tests / orchestrate (push) Waiting to run
run_tests / check_style (push) Waiting to run
deploy_nightly_docs / deploy_docs (push) Has been skipped
run_tests / clippy_windows (push) Blocked by required conditions
run_tests / clippy_linux (push) Blocked by required conditions
run_tests / clippy_mac (push) Blocked by required conditions
run_tests / clippy_mac_x86_64 (push) Blocked by required conditions
run_tests / run_tests_windows (push) Blocked by required conditions
run_tests / run_tests_linux (push) Blocked by required conditions
run_tests / run_tests_mac (push) Blocked by required conditions
run_tests / miri_scheduler (push) Blocked by required conditions
run_tests / doctests (push) Blocked by required conditions
run_tests / check_workspace_binaries (push) Blocked by required conditions
run_tests / build_visual_tests_binary (push) Blocked by required conditions
run_tests / check_wasm (push) Blocked by required conditions
run_tests / check_dependencies (push) Blocked by required conditions
run_tests / check_docs (push) Blocked by required conditions
run_tests / check_licenses (push) Blocked by required conditions
run_tests / check_scripts (push) Blocked by required conditions
run_tests / check_postgres_and_protobuf_migrations (push) Blocked by required conditions
run_tests / extension_tests (push) Blocked by required conditions
run_tests / tests_pass (push) Blocked by required conditions

HighlightedLabel would crash the application if any provided highlight
index was invalid. In theory, this should never happen. In practice,
this can happen due to race conditions at call sites.

After this change, we only panic in debug builds. In release builds, we
log an error and return a label with no highlights. The error message
includes the call site so that it's easier to fix the root cause.

Related to #57290

Part of FR-11.

Release Notes:

- N/A
This commit is contained in:
Oleksiy Syvokon 2026-05-21 07:01:28 +03:00 committed by GitHub
parent ddb847d03a
commit 7f7c21536e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 18 additions and 5 deletions

1
Cargo.lock generated
View file

@ -19197,6 +19197,7 @@ dependencies = [
"gpui_util",
"icons",
"itertools 0.14.0",
"log",
"menu",
"num-format",
"schemars 1.0.4",

View file

@ -20,6 +20,7 @@ gpui.workspace = true
gpui_macros.workspace = true
icons.workspace = true
itertools.workspace = true
log.workspace = true
menu.workspace = true
num-format.workspace = true
schemars.workspace = true
@ -36,5 +37,8 @@ windows.workspace = true
[dev-dependencies]
gpui = { workspace = true, features = ["test-support"] }
[package.metadata.cargo-machete]
ignored = ["log"]
[features]
default = []

View file

@ -1,6 +1,7 @@
use std::ops::Range;
use gpui::{FontWeight, HighlightStyle, StyleRefinement, StyledText};
use gpui_util::debug_panic;
use crate::{LabelCommon, LabelLike, LabelSize, LineHeightStyle, prelude::*};
@ -14,14 +15,21 @@ pub struct HighlightedLabel {
impl HighlightedLabel {
/// Constructs a label with the given characters highlighted.
/// Characters are identified by UTF-8 byte position.
pub fn new(label: impl Into<SharedString>, highlight_indices: Vec<usize>) -> Self {
#[track_caller]
pub fn new(label: impl Into<SharedString>, mut highlight_indices: Vec<usize>) -> Self {
let label = label.into();
for &run in &highlight_indices {
assert!(
label.is_char_boundary(run),
"highlight index {run} is not a valid UTF-8 boundary"
if let Some(index) = highlight_indices
.iter()
.find(|&i| !label.is_char_boundary(*i))
{
let location = std::panic::Location::caller();
debug_panic!(
"highlight index {index} is not a valid UTF-8 boundary (called from {location})"
);
highlight_indices.clear();
}
Self {
base: LabelLike::new(),
label,