diff options
| author | Dan Cross <dcross@google.com> | 2020-08-14 20:29:04 -0400 |
|---|---|---|
| committer | Dan Cross <dcross@google.com> | 2020-08-17 13:23:29 -0400 |
| commit | 6ad6d8c25c399cdc001ca65801017e8c5c51e9e2 (patch) | |
| tree | 08919bb4238e6ce83a1ea1c8e949445bbdbd3c79 | |
| parent | e8df0b893235aa06c6362d1a8646296310f79f81 (diff) | |
| download | rust-6ad6d8c25c399cdc001ca65801017e8c5c51e9e2.tar.gz rust-6ad6d8c25c399cdc001ca65801017e8c5c51e9e2.zip | |
librustc_metadata::locator: Properly detect file type.
Make sure to test for file types against the non-canonicalized name to avoid detecting the wrong type. Some systems save build artifacts into associative file stores that do not preserve extensions, and then link to those using conventionally-named symbolic links that are the arguments to `rustc` et al. If we canonicalize before testing the type, we resolve the symlink, the extension is lost and we might treat rlibs and rmetas as dylibs. The fix is to introduce a temporary to hold the canonicalized name, compare against the non-canonical name, and add a comment explaining what's going on for the would-be maintainer who sees a potential cleanup. Signed-off-by: Dan Cross <dcross@google.com>
| -rw-r--r-- | src/librustc_metadata/locator.rs | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs index bdd20a4bf6f..8fa14a44f52 100644 --- a/src/librustc_metadata/locator.rs +++ b/src/librustc_metadata/locator.rs @@ -685,13 +685,19 @@ impl<'a> CrateLocator<'a> { && file.ends_with(&self.target.options.dll_suffix) { // Make sure there's at most one rlib and at most one dylib. - let loc = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone()); + // Note to take care and match against the non-canonicalized name: + // some systems save build artifacts into content-addressed stores + // that do not preserve extensions, and then link to them using + // e.g. symbolic links. If we canonicalize too early, we resolve + // the symlink, the file type is lost and we might treat rlibs and + // rmetas as dylibs. + let loc_canon = fs::canonicalize(&loc).unwrap_or_else(|_| loc.clone()); if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") { - rlibs.insert(loc, PathKind::ExternFlag); + rlibs.insert(loc_canon, PathKind::ExternFlag); } else if loc.file_name().unwrap().to_str().unwrap().ends_with(".rmeta") { - rmetas.insert(loc, PathKind::ExternFlag); + rmetas.insert(loc_canon, PathKind::ExternFlag); } else { - dylibs.insert(loc, PathKind::ExternFlag); + dylibs.insert(loc_canon, PathKind::ExternFlag); } } else { self.rejected_via_filename |
