Only canonicalize executable path if it has relative directories

Otherwise symbolic links may also accidentally be resolved which may
lead to unexpected results in the case of 'coreutils', a binary
that depends on the executable name being a symbolic link.

This means a path like /bin/echo being canonicalized to /bin/coreutils
will loose all information about the desired functionality.

Test failures will occur if 'echo' is resolved that way and it's
not trivial to find the cause of it in the provided error messages.
This commit is contained in:
Sebastian Thiel 2021-10-21 17:03:58 +08:00
parent 7fbbf4e8f2
commit 0d06193bf1
No known key found for this signature in database
GPG Key ID: 9CB5EE7895E8268B

View File

@ -125,7 +125,19 @@ pub fn resolve_executable(exec: &Path) -> Result<PathBuf> {
if candidate.is_file() {
// PATH may have a component like "." in it, so we still need to
// canonicalize.
return Ok(candidate.canonicalize()?);
// Only do so if there are relative path components, otherwise symlinks to 'echo' may be resolved to their
// root program like 'coreutils' which relies on the executable name for proper function.
let has_relative_path_components = candidate.components().any(|c| {
matches!(
c,
std::path::Component::ParentDir | std::path::Component::CurDir
)
});
return Ok(if has_relative_path_components {
candidate.canonicalize()?
} else {
candidate
});
}
}