in tough/src/target_name.rs [108:169]
fn clean_name(name: &str) -> Result<String> {
// This causes something to panic, so we check for it early.
ensure!(name != "..", error::UnsafeTargetNameDotDotSnafu);
// Seems like bad things could happen if the target filename is the empty string.
ensure!(!name.is_empty(), error::UnsafeTargetNameEmptySnafu { name });
// If our name starts with absolute, then we need to remember this so we can restore it later.
let name_path = PathBuf::from(name);
let absolute = name_path.is_absolute();
let clean = {
let proposed = name_path
.absolutize_from(&PathBuf::from("/"))
.context(error::TargetNameResolveSnafu { name })?;
// `absolutize_from` will give us a path that starts with `/`, so we remove it if the
// original name did not start with `/`
if absolute {
// If `name` started with `/`, then we have nothing left to do because absolutize_from
// returns a rooted path.
proposed.to_path_buf()
} else {
let mut components = proposed.components();
// If the original name did not start with `/`, we need to remove the leading slash
// here because absolutize_from will return a rooted path.
let first_component = components
.next()
// If this error occurs then there is a bug or behavior change in absolutize_from.
.context(error::TargetNameComponentsEmptySnafu { name })?
.as_os_str();
// If the first component isn't `/` then there is a bug or behavior change in
// absolutize_from.
ensure!(
first_component == "/",
error::TargetNameRootMissingSnafu { name }
);
components.as_path().to_owned()
}
};
let final_name = clean
.as_os_str()
.to_str()
.context(error::PathUtf8Snafu { path: &clean })?
.to_string();
// Check again to make sure we didn't end up with an empty string.
ensure!(
!final_name.is_empty(),
error::UnsafeTargetNameEmptySnafu { name }
);
ensure!(
final_name != "/",
error::UnsafeTargetNameSlashSnafu { name }
);
Ok(final_name)
}