Skip to content

Commit dc89ec3

Browse files
OSS-Fuzz Teamcopybara-github
authored andcommitted
Strengthen the indexed path guarantees
As only built-in or absolute paths can come from the outside, we can guarantee that any path is either built-in, absolute, or relative to the single base path. This makes sure we cannot have any aliasing paths. Indexer-PiperOrigin-RevId: 779220498
1 parent 0714250 commit dc89ec3

File tree

7 files changed

+61
-35
lines changed

7 files changed

+61
-35
lines changed

infra/indexer/frontend/frontend_test.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3118,5 +3118,22 @@ TEST(FrontendTest, ImplicitComparisonInstantiation) {
31183118
RequiredEntityId(index, Entity::Kind::kClass, "", "TestTemplateClass",
31193119
"<T>", "snippet.cc", 11, 14)));
31203120
}
3121+
3122+
TEST(FrontendTest, CommandLineMacro) {
3123+
auto index = IndexSnippet("int MACRO;", {"-DMACRO=expansion"})->Export();
3124+
EXPECT_HAS_ENTITY(index, Entity::Kind::kVariable, "", "expansion", "",
3125+
"snippet.cc", 1, 1);
3126+
int found = 0;
3127+
for (const auto& index_entity : index.entities) {
3128+
if (index_entity.full_name() == "MACRO") {
3129+
EXPECT_EQ(index_entity.kind(), Entity::Kind::kMacro);
3130+
// NOTE(kartynnik): Why isn't this `<command line>`?
3131+
EXPECT_EQ(index.locations[index_entity.location_id()].path(),
3132+
"<built-in>");
3133+
++found;
3134+
}
3135+
}
3136+
EXPECT_EQ(found, 1);
3137+
}
31213138
} // namespace indexer
31223139
} // namespace oss_fuzz

infra/indexer/index/file_copier.cc

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,10 +51,8 @@ FileCopier::FileCopier(absl::string_view base_path,
5151
}
5252
}
5353

54-
std::string FileCopier::ToIndexPath(absl::string_view path) const {
55-
if (!path.starts_with('/')) {
56-
return std::string(path);
57-
}
54+
std::string FileCopier::AbsoluteToIndexPath(absl::string_view path) const {
55+
CHECK(path.starts_with("/")) << "Absolute path expected";
5856

5957
std::string result = std::string(path);
6058
if (!base_path_.empty() && absl::StartsWith(path, base_path_)) {
@@ -72,15 +70,8 @@ std::string FileCopier::ToIndexPath(absl::string_view path) const {
7270
}
7371

7472
void FileCopier::RegisterIndexedFile(absl::string_view index_path) {
75-
if (index_path.empty() || index_path.starts_with('<')) {
76-
// Built-in header or a location lacking the filename.
77-
return;
78-
}
79-
80-
{
81-
absl::MutexLock lock(&mutex_);
82-
indexed_files_.emplace(index_path);
83-
}
73+
absl::MutexLock lock(&mutex_);
74+
indexed_files_.emplace(index_path);
8475
}
8576

8677
void FileCopier::CopyIndexedFiles() {

infra/indexer/index/file_copier.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ class FileCopier {
3636
const std::vector<std::string>& extra_paths);
3737
FileCopier(const FileCopier&) = delete;
3838

39-
// Rewrites a path into the representation it will have in the index
40-
// (relative if within the source tree and absolute otherwise).
41-
std::string ToIndexPath(absl::string_view path) const;
39+
// Takes an absolute path. Rewrites this path into the representation it will
40+
// have in the index (relative if within the source tree and absolute
41+
// otherwise).
42+
std::string AbsoluteToIndexPath(absl::string_view path) const;
4243

4344
// `index_path` is expected to be produced by `ToIndexPath`.
4445
void RegisterIndexedFile(absl::string_view index_path);

infra/indexer/index/file_copier_unittest.cc

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,27 @@ std::optional<std::string> GetFileContents(const std::filesystem::path& path) {
4343
}
4444
} // namespace
4545

46-
TEST(FileCopierTest, ToIndexPath) {
46+
TEST(FileCopierTest, AbsoluteToIndexPath) {
4747
auto tmp_dir_path = std::filesystem::path(::testing::TempDir());
4848
auto base_path = tmp_dir_path / "src";
4949
auto index_path = tmp_dir_path / "idx";
5050
FileCopier file_copier(base_path.string(), index_path.string(), {"/"});
5151

52-
EXPECT_EQ(file_copier.ToIndexPath("/a/b/c/d.cc"), "/a/b/c/d.cc");
53-
EXPECT_EQ(file_copier.ToIndexPath((base_path / "a/b/c/d.cc").string()),
54-
"a/b/c/d.cc");
55-
EXPECT_EQ(file_copier.ToIndexPath("a/b/c/d.cc"), "a/b/c/d.cc");
52+
EXPECT_EQ(file_copier.AbsoluteToIndexPath("/a/b/c/d.cc"), "/a/b/c/d.cc");
53+
EXPECT_EQ(
54+
file_copier.AbsoluteToIndexPath((base_path / "a/b/c/d.cc").string()),
55+
"a/b/c/d.cc");
56+
EXPECT_DEATH(file_copier.AbsoluteToIndexPath("a/b/c/d.cc"),
57+
"Absolute path expected");
5658
}
5759

58-
TEST(FileCopierTest, ToIndexPathOutside) {
60+
TEST(FileCopierTest, AbsoluteToIndexPathOutside) {
5961
auto tmp_dir_path = std::filesystem::path(::testing::TempDir());
6062
auto base_path = tmp_dir_path / "src";
6163
auto index_path = tmp_dir_path / "idx";
6264
FileCopier file_copier(base_path.string(), index_path.string(), {"/sysroot"});
6365

64-
EXPECT_DEATH(file_copier.ToIndexPath("/a/b/c/d.cc"), "/a/b/c/d.cc");
66+
EXPECT_DEATH(file_copier.AbsoluteToIndexPath("/a/b/c/d.cc"), "/a/b/c/d.cc");
6567
}
6668

6769
TEST(FileCopierTest, FileCopying) {
@@ -85,9 +87,12 @@ TEST(FileCopierTest, FileCopying) {
8587
auto file_c_copy = index_path / "absolute" /
8688
sysroot_path.lexically_relative("/") / "y/z/c.cc";
8789

88-
file_copier.RegisterIndexedFile(file_copier.ToIndexPath(file_a.string()));
89-
file_copier.RegisterIndexedFile(file_copier.ToIndexPath(file_b.string()));
90-
file_copier.RegisterIndexedFile(file_copier.ToIndexPath(file_c.string()));
90+
file_copier.RegisterIndexedFile(
91+
file_copier.AbsoluteToIndexPath(file_a.string()));
92+
file_copier.RegisterIndexedFile(
93+
file_copier.AbsoluteToIndexPath(file_b.string()));
94+
file_copier.RegisterIndexedFile(
95+
file_copier.AbsoluteToIndexPath(file_c.string()));
9196

9297
file_copier.CopyIndexedFiles();
9398

infra/indexer/index/in_memory_index.cc

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ void InMemoryIndex::Merge(const InMemoryIndex& other) {
196196
std::vector<LocationId> new_location_ids(other.locations_.size(),
197197
kInvalidLocationId);
198198
for (const auto& [location, id] : other.locations_) {
199-
new_location_ids[id] = GetLocationId(location);
199+
new_location_ids[id] = GetIdForLocationWithIndexPath(location);
200200
}
201201

202202
// We need to update the location_id for entities, and the entity_id and
@@ -276,15 +276,22 @@ void InMemoryIndex::Expand(size_t locations_count, size_t entities_count,
276276
references_.reserve(references_.size() + references_count);
277277
}
278278

279-
LocationId InMemoryIndex::GetLocationId(const Location& location) {
280-
// Adjust paths within the base_path to be relative paths.
281-
Location new_location = location;
282-
new_location.path_ = file_copier_.ToIndexPath(location.path());
279+
LocationId InMemoryIndex::GetLocationId(Location location) {
280+
if (location.is_real()) {
281+
// Adjust paths within the base_path to be relative paths.
282+
location.path_ = file_copier_.AbsoluteToIndexPath(location.path());
283+
}
284+
return GetIdForLocationWithIndexPath(location);
285+
}
283286

284-
auto [iter, inserted] = locations_.insert({new_location, next_location_id_});
287+
LocationId InMemoryIndex::GetIdForLocationWithIndexPath(
288+
const Location& location) {
289+
auto [iter, inserted] = locations_.insert({location, next_location_id_});
285290
if (inserted) {
286291
next_location_id_++;
287-
file_copier_.RegisterIndexedFile(new_location.path());
292+
if (location.is_real()) {
293+
file_copier_.RegisterIndexedFile(location.path());
294+
}
288295
}
289296

290297
return iter->second;

infra/indexer/index/in_memory_index.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,8 @@ class InMemoryIndex {
4747
// The `GetXxxId` functions return the id of an existing, matching object if
4848
// there is already one in the index, or allocate a new id if there is not an
4949
// identical object in the index.
50-
LocationId GetLocationId(const Location& location);
50+
// `GetLocationId` expects a location with an absolute path if not built-in.
51+
LocationId GetLocationId(Location location);
5152
EntityId GetEntityId(const Entity& entity);
5253
ReferenceId GetReferenceId(const Reference& reference);
5354

@@ -57,6 +58,9 @@ class InMemoryIndex {
5758
private:
5859
FileCopier& file_copier_;
5960

61+
// Like `GetLocationId`, but requires the path to be already index-adjusted.
62+
LocationId GetIdForLocationWithIndexPath(const Location& location);
63+
6064
// Although we could sort location_lookup_ in advance, the performance impact
6165
// on indexing if we use a btree_map is significant, and it's much faster
6266
// to sort the index at the end.

infra/indexer/index/types.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,8 @@ constexpr LocationId kInvalidLocationId = 0xffffffffffffffffull;
3838
constexpr EntityId kInvalidEntityId = 0xffffffffffffffffull;
3939

4040
inline bool IsRealPath(absl::string_view path) {
41-
return !path.empty() && !path.starts_with("<");
41+
// Examples of built-in paths: `<built-in>` and `<command-line>`.
42+
return !path.empty() && !path.starts_with('<');
4243
}
4344

4445
// Represents a source-file location.

0 commit comments

Comments
 (0)