rustc_driver: avoid fallible conversions

Use `std::path::PathBuf` rather than `String`; use `std::env::var_os`
rather than `std::env::var`. These changes avoid a number of error paths
which can arise in the presence of non-UTF-8 paths.
This commit is contained in:
Tamir Duberstein 2023-10-06 08:22:35 -04:00
parent 7654d4b398
commit a081007265
No known key found for this signature in database
2 changed files with 18 additions and 15 deletions

View File

@ -1290,14 +1290,18 @@ pub fn ice_path() -> &'static Option<PathBuf> {
if let Some(s) = std::env::var_os("RUST_BACKTRACE") && s == "0" { if let Some(s) = std::env::var_os("RUST_BACKTRACE") && s == "0" {
return None; return None;
} }
let mut path = match std::env::var("RUSTC_ICE").as_deref() { let mut path = match std::env::var_os("RUSTC_ICE") {
// Explicitly opting out of writing ICEs to disk. Some(s) => {
Ok("0") => return None, if s == "0" {
Ok(s) => PathBuf::from(s), // Explicitly opting out of writing ICEs to disk.
Err(_) => std::env::current_dir().unwrap_or_default(), return None;
}
PathBuf::from(s)
}
None => std::env::current_dir().unwrap_or_default(),
}; };
let now: OffsetDateTime = SystemTime::now().into(); let now: OffsetDateTime = SystemTime::now().into();
let file_now = now.format(&Rfc3339).unwrap_or(String::new()); let file_now = now.format(&Rfc3339).unwrap_or_default();
let pid = std::process::id(); let pid = std::process::id();
path.push(format!("rustc-ice-{file_now}-{pid}.txt")); path.push(format!("rustc-ice-{file_now}-{pid}.txt"));
Some(path) Some(path)
@ -1411,12 +1415,11 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info:
static FIRST_PANIC: AtomicBool = AtomicBool::new(true); static FIRST_PANIC: AtomicBool = AtomicBool::new(true);
let file = if let Some(path) = ice_path().as_ref() { let file = if let Some(path) = ice_path() {
// Create the ICE dump target file. // Create the ICE dump target file.
match crate::fs::File::options().create(true).append(true).open(&path) { match crate::fs::File::options().create(true).append(true).open(&path) {
Ok(mut file) => { Ok(mut file) => {
handler handler.emit_note(session_diagnostics::IcePath { path: path.clone() });
.emit_note(session_diagnostics::IcePath { path: path.display().to_string() });
if FIRST_PANIC.swap(false, Ordering::SeqCst) { if FIRST_PANIC.swap(false, Ordering::SeqCst) {
let _ = write!(file, "\n\nrustc version: {version}\nplatform: {triple}"); let _ = write!(file, "\n\nrustc version: {version}\nplatform: {triple}");
} }
@ -1425,10 +1428,10 @@ pub fn report_ice(info: &panic::PanicInfo<'_>, bug_report_url: &str, extra_info:
Err(err) => { Err(err) => {
// The path ICE couldn't be written to disk, provide feedback to the user as to why. // The path ICE couldn't be written to disk, provide feedback to the user as to why.
handler.emit_warning(session_diagnostics::IcePathError { handler.emit_warning(session_diagnostics::IcePathError {
path: path.display().to_string(), path: path.clone(),
error: err.to_string(), error: err.to_string(),
env_var: std::env::var("RUSTC_ICE") env_var: std::env::var_os("RUSTC_ICE")
.ok() .map(PathBuf::from)
.map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }), .map(|env_var| session_diagnostics::IcePathErrorEnv { env_var }),
}); });
handler.emit_note(session_diagnostics::IceVersion { version, triple }); handler.emit_note(session_diagnostics::IceVersion { version, triple });

View File

@ -52,13 +52,13 @@ pub(crate) struct IceVersion<'a> {
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(driver_impl_ice_path)] #[diag(driver_impl_ice_path)]
pub(crate) struct IcePath { pub(crate) struct IcePath {
pub path: String, pub path: std::path::PathBuf,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(driver_impl_ice_path_error)] #[diag(driver_impl_ice_path_error)]
pub(crate) struct IcePathError { pub(crate) struct IcePathError {
pub path: String, pub path: std::path::PathBuf,
pub error: String, pub error: String,
#[subdiagnostic] #[subdiagnostic]
pub env_var: Option<IcePathErrorEnv>, pub env_var: Option<IcePathErrorEnv>,
@ -67,7 +67,7 @@ pub(crate) struct IcePathError {
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
#[note(driver_impl_ice_path_error_env)] #[note(driver_impl_ice_path_error_env)]
pub(crate) struct IcePathErrorEnv { pub(crate) struct IcePathErrorEnv {
pub env_var: String, pub env_var: std::path::PathBuf,
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]