Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit c71cfee

Browse files
committedApr 19, 2024··
Fix ICE when there is a non-Unicode entry in the incremental crate directory
1 parent 5260893 commit c71cfee

File tree

3 files changed

+40
-17
lines changed
  • compiler/rustc_incremental/src/persist
  • tests/run-make/non-unicode-in-incremental-dir

3 files changed

+40
-17
lines changed
 

‎compiler/rustc_incremental/src/persist/fs.rs

+19-17
Original file line numberDiff line numberDiff line change
@@ -162,8 +162,11 @@ pub fn query_cache_path(sess: &Session) -> PathBuf {
162162
fn lock_file_path(session_dir: &Path) -> PathBuf {
163163
let crate_dir = session_dir.parent().unwrap();
164164

165-
let directory_name = session_dir.file_name().unwrap().to_string_lossy();
166-
assert_no_characters_lost(&directory_name);
165+
let directory_name = session_dir
166+
.file_name()
167+
.unwrap()
168+
.to_str()
169+
.expect("malformed session dir name: contains non-Unicode characters");
167170

168171
let dash_indices: Vec<_> = directory_name.match_indices('-').map(|(idx, _)| idx).collect();
169172
if dash_indices.len() != 3 {
@@ -329,8 +332,11 @@ pub fn finalize_session_directory(sess: &Session, svh: Option<Svh>) {
329332

330333
debug!("finalize_session_directory() - session directory: {}", incr_comp_session_dir.display());
331334

332-
let old_sub_dir_name = incr_comp_session_dir.file_name().unwrap().to_string_lossy();
333-
assert_no_characters_lost(&old_sub_dir_name);
335+
let old_sub_dir_name = incr_comp_session_dir
336+
.file_name()
337+
.unwrap()
338+
.to_str()
339+
.expect("malformed session dir name: contains non-Unicode characters");
334340

335341
// Keep the 's-{timestamp}-{random-number}' prefix, but replace the
336342
// '-working' part with the SVH of the crate
@@ -527,8 +533,10 @@ where
527533
for session_dir in iter {
528534
debug!("find_source_directory_in_iter - inspecting `{}`", session_dir.display());
529535

530-
let directory_name = session_dir.file_name().unwrap().to_string_lossy();
531-
assert_no_characters_lost(&directory_name);
536+
let Some(directory_name) = session_dir.file_name().unwrap().to_str() else {
537+
debug!("find_source_directory_in_iter - ignoring");
538+
continue;
539+
};
532540

533541
if source_directories_already_tried.contains(&session_dir)
534542
|| !is_session_directory(&directory_name)
@@ -619,12 +627,6 @@ fn crate_path(sess: &Session) -> PathBuf {
619627
incr_dir.join(crate_name)
620628
}
621629

622-
fn assert_no_characters_lost(s: &str) {
623-
if s.contains('\u{FFFD}') {
624-
bug!("Could not losslessly convert '{}'.", s)
625-
}
626-
}
627-
628630
fn is_old_enough_to_be_collected(timestamp: SystemTime) -> bool {
629631
timestamp < SystemTime::now() - Duration::from_secs(10)
630632
}
@@ -657,14 +659,14 @@ pub(crate) fn garbage_collect_session_directories(sess: &Session) -> io::Result<
657659
};
658660

659661
let entry_name = dir_entry.file_name();
660-
let entry_name = entry_name.to_string_lossy();
662+
let Some(entry_name) = entry_name.to_str() else {
663+
continue;
664+
};
661665

662666
if is_session_directory_lock_file(&entry_name) {
663-
assert_no_characters_lost(&entry_name);
664-
lock_files.insert(entry_name.into_owned());
667+
lock_files.insert(entry_name.to_string());
665668
} else if is_session_directory(&entry_name) {
666-
assert_no_characters_lost(&entry_name);
667-
session_directories.insert(entry_name.into_owned());
669+
session_directories.insert(entry_name.to_string());
668670
} else {
669671
// This is something we don't know, leave it alone
670672
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
extern crate run_make_support;
2+
3+
use run_make_support::{rustc, tmp_dir};
4+
5+
fn main() {
6+
#[cfg(unix)]
7+
let non_unicode: &std::ffi::OsStr = std::os::unix::ffi::OsStrExt::from_bytes(&[0xFF]);
8+
#[cfg(windows)]
9+
let non_unicode: std::ffi::OsString = std::os::windows::ffi::OsStringExt::from_wide(&[0xD800]);
10+
if std::fs::create_dir(tmp_dir().join(&non_unicode)).is_err() {
11+
// Filesystem doesn't support non-Unicode paths.
12+
return;
13+
}
14+
let incr_dir = tmp_dir().join("incr-dir");
15+
rustc().input("foo.rs").incremental(&incr_dir).run();
16+
for crate_dir in std::fs::read_dir(&incr_dir).unwrap() {
17+
std::fs::create_dir(crate_dir.unwrap().path().join(&non_unicode)).unwrap();
18+
}
19+
rustc().input("foo.rs").incremental(&incr_dir).run();
20+
}

0 commit comments

Comments
 (0)
Please sign in to comment.