util: Fix path truncation when the file name repeats in a parent dir

`PathWithPosition::parse_str` stripped the position suffix by searching
the whole path for the captured file name, so `foo/foo:10:2` was cut at
the first `foo` and parsed as `foo`. The same happened for
`main.rs-backup/src/main.rs:10:2`.

The captured file name is a slice of the last path component, so cut the
path right after it instead. Switching to `rsplit_once` would not work
either, since the last occurrence lands inside the position suffix for
numeric names like `1/1:1:1`.

Closes #64174
This commit is contained in:
dualfroz committed 2026-10-02 16:43:56 +02:00
1 parent f3eecab1c6
commit ba0a85b19f
1 file changed
+52 -2
+52 -2
View File
@@ -662,8 +662,10 @@ impl PathWithPosition {
let row = maybe_row.parse::<u32>().ok();
let column = maybe_column.parse::<u32>().ok();
let (_, suffix) = trimmed.split_once(file_name).unwrap();
let path_without_suffix = &trimmed[..trimmed.len() - suffix.len()];
// `file_name` borrows from the last component of `trimmed`, so cut right after it
// instead of searching for its text, which may also appear in a parent directory.
let file_name_start = file_name.as_ptr() as usize - trimmed.as_ptr() as usize;
let path_without_suffix = &trimmed[..file_name_start + file_name.len()];
Self {
path: Path::new(path_without_suffix).to_path_buf(),
@@ -2512,6 +2514,54 @@ mod tests {
);
}
#[perf]
fn path_with_position_parse_file_name_repeated_in_path() {
assert_eq!(
PathWithPosition::parse_str("foo/foo:10:2"),
PathWithPosition {
path: PathBuf::from("foo/foo"),
row: Some(10),
column: Some(2),
}
);
assert_eq!(
PathWithPosition::parse_str("foo/foo(10,2)"),
PathWithPosition {
path: PathBuf::from("foo/foo"),
row: Some(10),
column: Some(2),
}
);
assert_eq!(
PathWithPosition::parse_str("main.rs-backup/src/main.rs:10:2"),
PathWithPosition {
path: PathBuf::from("main.rs-backup/src/main.rs"),
row: Some(10),
column: Some(2),
}
);
assert_eq!(
PathWithPosition::parse_str("1/1:1:1"),
PathWithPosition {
path: PathBuf::from("1/1"),
row: Some(1),
column: Some(1),
}
);
assert_eq!(
PathWithPosition::parse_str("日本/日本:3"),
PathWithPosition {
path: PathBuf::from("日本/日本"),
row: Some(3),
column: None,
}
);
}
#[perf]
#[cfg(target_os = "windows")]
fn path_with_position_parse_windows_path() {