Skip to content

Commit 7a3beac

Browse files
committed
Swift: resolve symlinks conditionally
1 parent e7a48b4 commit 7a3beac

File tree

5 files changed

+53
-22
lines changed

5 files changed

+53
-22
lines changed

swift/extractor/SwiftExtractor.cpp

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,12 @@
1212
#include "swift/extractor/translators/SwiftVisitor.h"
1313
#include "swift/extractor/TargetTrapFile.h"
1414
#include "swift/extractor/SwiftBuiltinSymbols.h"
15+
#include "swift/extractor/infra/Path.h"
1516

1617
using namespace codeql;
1718
using namespace std::string_literals;
1819
namespace fs = std::filesystem;
1920

20-
static fs::path toPath(llvm::StringRef s) {
21-
return {static_cast<std::string_view>(s)};
22-
}
23-
2421
static void ensureDirectory(const char* label, const fs::path& dir) {
2522
std::error_code ec;
2623
fs::create_directories(dir, ec);
@@ -34,7 +31,7 @@ static void archiveFile(const SwiftExtractorConfiguration& config, swift::Source
3431
ensureDirectory("TRAP", config.trapDir);
3532
ensureDirectory("source archive", config.sourceArchiveDir);
3633

37-
fs::path srcFilePath = fs::absolute(toPath(file.getFilename()));
34+
fs::path srcFilePath = codeql::getCodeQLPath(file.getFilename());
3835
auto dstFilePath = config.sourceArchiveDir;
3936
dstFilePath += srcFilePath;
4037

@@ -60,7 +57,7 @@ static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primar
6057
// Moreover, pcm files may come from caches located in different directories, but are
6158
// unambiguously identified by the base file name, so we can discard the absolute directory
6259
fs::path filename = "/pcms";
63-
filename /= toPath(module.getModuleFilename()).filename();
60+
filename /= getCodeQLPath(module.getModuleFilename()).filename();
6461
filename += "-";
6562
filename += module.getName().str();
6663
return filename;
@@ -69,7 +66,7 @@ static fs::path getFilename(swift::ModuleDecl& module, swift::SourceFile* primar
6966
// The Builtin module has an empty filename, let's fix that
7067
return "/__Builtin__";
7168
}
72-
auto filename = toPath(module.getModuleFilename());
69+
auto filename = getCodeQLPath(module.getModuleFilename());
7370
// there is a special case of a module without an actual filename reporting `<imports>`: in this
7471
// case we want to avoid the `<>` characters, in case a dirty DB is imported on Windows
7572
if (filename == "<imports>") {

swift/extractor/infra/Path.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "swift/extractor/infra/Path.h"
2+
#include <iostream>
3+
#include <unistd.h>
4+
5+
namespace codeql {
6+
7+
static bool shouldCanonicalize() {
8+
auto preserve = getenv("CODEQL_PRESERVE_SYMLINKS");
9+
if (preserve && std::string(preserve) == "true") {
10+
return false;
11+
}
12+
preserve = getenv("SEMMLE_PRESERVE_SYMLINKS");
13+
if (preserve && std::string(preserve) == "true") {
14+
return false;
15+
}
16+
return true;
17+
}
18+
19+
std::filesystem::path getCodeQLPath(std::string_view path) {
20+
// TODO: this needs more testing
21+
// TODO: check canonicalization of names on a case insensitive filesystems
22+
std::error_code ec;
23+
std::filesystem::path ret = {};
24+
static const auto canonicalize = shouldCanonicalize();
25+
if (canonicalize) {
26+
ret = std::filesystem::canonical(path, ec);
27+
} else {
28+
ret = std::filesystem::absolute(path, ec);
29+
}
30+
if (ec) {
31+
std::cerr << "Cannot get " << (canonicalize ? "canonical" : "absolute")
32+
<< " path: " << std::quoted(path) << ": " << ec.message() << "\n";
33+
return {};
34+
}
35+
return ret;
36+
}
37+
38+
} // namespace codeql

swift/extractor/infra/Path.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#pragma once
2+
3+
#include <filesystem>
4+
5+
namespace codeql {
6+
std::filesystem::path getCodeQLPath(std::string_view path);
7+
}

swift/extractor/infra/SwiftLocationExtractor.cpp

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,10 @@
55
#include "swift/extractor/trap/generated/TrapEntries.h"
66
#include "swift/extractor/trap/generated/TrapClasses.h"
77
#include "swift/extractor/infra/SwiftLocationExtractor.h"
8+
#include "swift/extractor/infra/Path.h"
89

910
using namespace codeql;
1011

11-
static std::filesystem::path getFilePath(std::string_view path) {
12-
// TODO: this needs more testing
13-
// TODO: check canonicalization of names on a case insensitive filesystems
14-
// TODO: make symlink resolution conditional on CODEQL_PRESERVE_SYMLINKS=true
15-
std::error_code ec;
16-
auto ret = std::filesystem::canonical(path, ec);
17-
if (ec) {
18-
std::cerr << "Cannot get real path: " << std::quoted(path) << ": " << ec.message() << "\n";
19-
return {};
20-
}
21-
return ret;
22-
}
23-
2412
void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceManager,
2513
swift::SourceLoc start,
2614
swift::SourceLoc end,
@@ -29,7 +17,7 @@ void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceMa
2917
// invalid locations seem to come from entities synthesized by the compiler
3018
return;
3119
}
32-
auto file = getFilePath(sourceManager.getDisplayNameForLoc(start));
20+
auto file = getCodeQLPath(sourceManager.getDisplayNameForLoc(start));
3321
DbLocation entry{{}};
3422
entry.file = fetchFileLabel(file);
3523
std::tie(entry.start_line, entry.start_column) = sourceManager.getLineAndColumnInBuffer(start);
@@ -42,7 +30,7 @@ void SwiftLocationExtractor::attachLocation(const swift::SourceManager& sourceMa
4230
}
4331

4432
void SwiftLocationExtractor::emitFile(llvm::StringRef path) {
45-
fetchFileLabel(getFilePath(path));
33+
fetchFileLabel(getCodeQLPath(path));
4634
}
4735

4836
TrapLabel<FileTag> SwiftLocationExtractor::fetchFileLabel(const std::filesystem::path& file) {
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
| file://:0:0:0:0 | |
22
| main.swift:0:0:0:0 | main.swift |
33
| preserve/Package.swift:0:0:0:0 | preserve/Package.swift |
4+
| preserve/Sources/A.swift:0:0:0:0 | preserve/Sources/A.swift |
45
| resolve/Package.swift:0:0:0:0 | resolve/Package.swift |

0 commit comments

Comments
 (0)