aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Support/VirtualFileSystem.cpp
diff options
context:
space:
mode:
authorBen Langmuir <blangmuir@apple.com>2024-03-15 09:01:41 -0700
committerGitHub <noreply@github.com>2024-03-15 09:01:41 -0700
commit5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56 (patch)
treea09d36f67ec5df9cf40ab3ddaa514686c6bb9950 /llvm/lib/Support/VirtualFileSystem.cpp
parent0ed7a5a9a1d4297e30c7992379ff292cd1aa3828 (diff)
downloadllvm-5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56.zip
llvm-5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56.tar.gz
llvm-5a8a7ee9d12d7cd3680c7bc14a4750bd44d99c56.tar.bz2
[llvm][vfs] Preserve paths for fallback/fallthrough in RedirectingFileSystem (#85307)
When we lookup in the external filesystem, do not remove . and .. components from the original path. For .. this is a correctness issue in the presence of symlinks, while for . it is simply better practice to preserve the original path to better match the behaviour of other filesystems. The only modification we need is to apply the working directory, since it could differ from the external filesystem. rdar://123655660
Diffstat (limited to 'llvm/lib/Support/VirtualFileSystem.cpp')
-rw-r--r--llvm/lib/Support/VirtualFileSystem.cpp88
1 files changed, 43 insertions, 45 deletions
diff --git a/llvm/lib/Support/VirtualFileSystem.cpp b/llvm/lib/Support/VirtualFileSystem.cpp
index 051dd2a..057f8eae 100644
--- a/llvm/lib/Support/VirtualFileSystem.cpp
+++ b/llvm/lib/Support/VirtualFileSystem.cpp
@@ -1344,7 +1344,7 @@ std::error_code RedirectingFileSystem::isLocal(const Twine &Path_,
SmallString<256> Path;
Path_.toVector(Path);
- if (makeCanonical(Path))
+ if (makeAbsolute(Path))
return {};
return ExternalFS->isLocal(Path, Result);
@@ -1411,7 +1411,7 @@ directory_iterator RedirectingFileSystem::dir_begin(const Twine &Dir,
SmallString<256> Path;
Dir.toVector(Path);
- EC = makeCanonical(Path);
+ EC = makeAbsolute(Path);
if (EC)
return {};
@@ -2261,8 +2261,8 @@ void RedirectingFileSystem::LookupResult::getPath(
llvm::sys::path::append(Result, E->getName());
}
-std::error_code
-RedirectingFileSystem::makeCanonical(SmallVectorImpl<char> &Path) const {
+std::error_code RedirectingFileSystem::makeCanonicalForLookup(
+ SmallVectorImpl<char> &Path) const {
if (std::error_code EC = makeAbsolute(Path))
return EC;
@@ -2277,12 +2277,16 @@ RedirectingFileSystem::makeCanonical(SmallVectorImpl<char> &Path) const {
ErrorOr<RedirectingFileSystem::LookupResult>
RedirectingFileSystem::lookupPath(StringRef Path) const {
+ llvm::SmallString<128> CanonicalPath(Path);
+ if (std::error_code EC = makeCanonicalForLookup(CanonicalPath))
+ return EC;
+
// RedirectOnly means the VFS is always used.
if (UsageTrackingActive && Redirection == RedirectKind::RedirectOnly)
HasBeenUsed = true;
- sys::path::const_iterator Start = sys::path::begin(Path);
- sys::path::const_iterator End = sys::path::end(Path);
+ sys::path::const_iterator Start = sys::path::begin(CanonicalPath);
+ sys::path::const_iterator End = sys::path::end(CanonicalPath);
llvm::SmallVector<Entry *, 32> Entries;
for (const auto &Root : Roots) {
ErrorOr<RedirectingFileSystem::LookupResult> Result =
@@ -2358,14 +2362,14 @@ static Status getRedirectedFileStatus(const Twine &OriginalPath,
}
ErrorOr<Status> RedirectingFileSystem::status(
- const Twine &CanonicalPath, const Twine &OriginalPath,
+ const Twine &LookupPath, const Twine &OriginalPath,
const RedirectingFileSystem::LookupResult &Result) {
if (std::optional<StringRef> ExtRedirect = Result.getExternalRedirect()) {
- SmallString<256> CanonicalRemappedPath((*ExtRedirect).str());
- if (std::error_code EC = makeCanonical(CanonicalRemappedPath))
+ SmallString<256> RemappedPath((*ExtRedirect).str());
+ if (std::error_code EC = makeAbsolute(RemappedPath))
return EC;
- ErrorOr<Status> S = ExternalFS->status(CanonicalRemappedPath);
+ ErrorOr<Status> S = ExternalFS->status(RemappedPath);
if (!S)
return S;
S = Status::copyWithNewName(*S, *ExtRedirect);
@@ -2375,13 +2379,13 @@ ErrorOr<Status> RedirectingFileSystem::status(
}
auto *DE = cast<RedirectingFileSystem::DirectoryEntry>(Result.E);
- return Status::copyWithNewName(DE->getStatus(), CanonicalPath);
+ return Status::copyWithNewName(DE->getStatus(), LookupPath);
}
ErrorOr<Status>
-RedirectingFileSystem::getExternalStatus(const Twine &CanonicalPath,
+RedirectingFileSystem::getExternalStatus(const Twine &LookupPath,
const Twine &OriginalPath) const {
- auto Result = ExternalFS->status(CanonicalPath);
+ auto Result = ExternalFS->status(LookupPath);
// The path has been mapped by some nested VFS, don't override it with the
// original path.
@@ -2391,38 +2395,37 @@ RedirectingFileSystem::getExternalStatus(const Twine &CanonicalPath,
}
ErrorOr<Status> RedirectingFileSystem::status(const Twine &OriginalPath) {
- SmallString<256> CanonicalPath;
- OriginalPath.toVector(CanonicalPath);
+ SmallString<256> Path;
+ OriginalPath.toVector(Path);
- if (std::error_code EC = makeCanonical(CanonicalPath))
+ if (std::error_code EC = makeAbsolute(Path))
return EC;
if (Redirection == RedirectKind::Fallback) {
// Attempt to find the original file first, only falling back to the
// mapped file if that fails.
- ErrorOr<Status> S = getExternalStatus(CanonicalPath, OriginalPath);
+ ErrorOr<Status> S = getExternalStatus(Path, OriginalPath);
if (S)
return S;
}
- ErrorOr<RedirectingFileSystem::LookupResult> Result =
- lookupPath(CanonicalPath);
+ ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath(Path);
if (!Result) {
// Was not able to map file, fallthrough to using the original path if
// that was the specified redirection type.
if (Redirection == RedirectKind::Fallthrough &&
isFileNotFound(Result.getError()))
- return getExternalStatus(CanonicalPath, OriginalPath);
+ return getExternalStatus(Path, OriginalPath);
return Result.getError();
}
- ErrorOr<Status> S = status(CanonicalPath, OriginalPath, *Result);
+ ErrorOr<Status> S = status(Path, OriginalPath, *Result);
if (!S && Redirection == RedirectKind::Fallthrough &&
isFileNotFound(S.getError(), Result->E)) {
// Mapped the file but it wasn't found in the underlying filesystem,
// fallthrough to using the original path if that was the specified
// redirection type.
- return getExternalStatus(CanonicalPath, OriginalPath);
+ return getExternalStatus(Path, OriginalPath);
}
return S;
@@ -2471,30 +2474,27 @@ File::getWithPath(ErrorOr<std::unique_ptr<File>> Result, const Twine &P) {
ErrorOr<std::unique_ptr<File>>
RedirectingFileSystem::openFileForRead(const Twine &OriginalPath) {
- SmallString<256> CanonicalPath;
- OriginalPath.toVector(CanonicalPath);
+ SmallString<256> Path;
+ OriginalPath.toVector(Path);
- if (std::error_code EC = makeCanonical(CanonicalPath))
+ if (std::error_code EC = makeAbsolute(Path))
return EC;
if (Redirection == RedirectKind::Fallback) {
// Attempt to find the original file first, only falling back to the
// mapped file if that fails.
- auto F = File::getWithPath(ExternalFS->openFileForRead(CanonicalPath),
- OriginalPath);
+ auto F = File::getWithPath(ExternalFS->openFileForRead(Path), OriginalPath);
if (F)
return F;
}
- ErrorOr<RedirectingFileSystem::LookupResult> Result =
- lookupPath(CanonicalPath);
+ ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath(Path);
if (!Result) {
// Was not able to map file, fallthrough to using the original path if
// that was the specified redirection type.
if (Redirection == RedirectKind::Fallthrough &&
isFileNotFound(Result.getError()))
- return File::getWithPath(ExternalFS->openFileForRead(CanonicalPath),
- OriginalPath);
+ return File::getWithPath(ExternalFS->openFileForRead(Path), OriginalPath);
return Result.getError();
}
@@ -2502,22 +2502,21 @@ RedirectingFileSystem::openFileForRead(const Twine &OriginalPath) {
return make_error_code(llvm::errc::invalid_argument);
StringRef ExtRedirect = *Result->getExternalRedirect();
- SmallString<256> CanonicalRemappedPath(ExtRedirect.str());
- if (std::error_code EC = makeCanonical(CanonicalRemappedPath))
+ SmallString<256> RemappedPath(ExtRedirect.str());
+ if (std::error_code EC = makeAbsolute(RemappedPath))
return EC;
auto *RE = cast<RedirectingFileSystem::RemapEntry>(Result->E);
- auto ExternalFile = File::getWithPath(
- ExternalFS->openFileForRead(CanonicalRemappedPath), ExtRedirect);
+ auto ExternalFile =
+ File::getWithPath(ExternalFS->openFileForRead(RemappedPath), ExtRedirect);
if (!ExternalFile) {
if (Redirection == RedirectKind::Fallthrough &&
isFileNotFound(ExternalFile.getError(), Result->E)) {
// Mapped the file but it wasn't found in the underlying filesystem,
// fallthrough to using the original path if that was the specified
// redirection type.
- return File::getWithPath(ExternalFS->openFileForRead(CanonicalPath),
- OriginalPath);
+ return File::getWithPath(ExternalFS->openFileForRead(Path), OriginalPath);
}
return ExternalFile;
}
@@ -2537,28 +2536,27 @@ RedirectingFileSystem::openFileForRead(const Twine &OriginalPath) {
std::error_code
RedirectingFileSystem::getRealPath(const Twine &OriginalPath,
SmallVectorImpl<char> &Output) const {
- SmallString<256> CanonicalPath;
- OriginalPath.toVector(CanonicalPath);
+ SmallString<256> Path;
+ OriginalPath.toVector(Path);
- if (std::error_code EC = makeCanonical(CanonicalPath))
+ if (std::error_code EC = makeAbsolute(Path))
return EC;
if (Redirection == RedirectKind::Fallback) {
// Attempt to find the original file first, only falling back to the
// mapped file if that fails.
- std::error_code EC = ExternalFS->getRealPath(CanonicalPath, Output);
+ std::error_code EC = ExternalFS->getRealPath(Path, Output);
if (!EC)
return EC;
}
- ErrorOr<RedirectingFileSystem::LookupResult> Result =
- lookupPath(CanonicalPath);
+ ErrorOr<RedirectingFileSystem::LookupResult> Result = lookupPath(Path);
if (!Result) {
// Was not able to map file, fallthrough to using the original path if
// that was the specified redirection type.
if (Redirection == RedirectKind::Fallthrough &&
isFileNotFound(Result.getError()))
- return ExternalFS->getRealPath(CanonicalPath, Output);
+ return ExternalFS->getRealPath(Path, Output);
return Result.getError();
}
@@ -2571,7 +2569,7 @@ RedirectingFileSystem::getRealPath(const Twine &OriginalPath,
// Mapped the file but it wasn't found in the underlying filesystem,
// fallthrough to using the original path if that was the specified
// redirection type.
- return ExternalFS->getRealPath(CanonicalPath, Output);
+ return ExternalFS->getRealPath(Path, Output);
}
return P;
}