Skip to content

Commit 972db39

Browse files
committed
More advanced logic for relative paths in the fetcher config
Accounts for files that could be in parent directories. Bug: b/461569369
1 parent 012a83c commit 972db39

File tree

2 files changed

+33
-16
lines changed

2 files changed

+33
-16
lines changed

base/cvd/cuttlefish/host/libs/config/fetcher_config.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -153,8 +153,11 @@ Json::Value CvdFileToJson(const CvdFile& cvd_file) {
153153
return json;
154154
}
155155

156-
Result<std::string> NormalizePath(std::string path) {
157-
CF_EXPECT(!absl::StrContains(path, ".."));
156+
std::string NormalizePath(std::string path) {
157+
std::string original_path = path;
158+
while (absl::StrContains(path, "/./")) {
159+
absl::StrReplaceAll({{"/./", "/"}}, &path);
160+
}
158161
while (absl::StrContains(path, "//")) {
159162
absl::StrReplaceAll({{"//", "/"}}, &path);
160163
}
@@ -167,6 +170,27 @@ Result<std::string> NormalizePath(std::string path) {
167170
return path;
168171
}
169172

173+
std::string FindRelativePath(std::string_view path, std::string relative_dir) {
174+
if (!absl::EndsWith(relative_dir, "/")) {
175+
relative_dir += "/";
176+
}
177+
int num_parents = 0;
178+
std::string_view common_parent = relative_dir;
179+
while (!absl::StartsWith(path, common_parent)) {
180+
num_parents++;
181+
size_t last_slash = common_parent.find_last_of("/");
182+
CHECK(last_slash != std::string::npos);
183+
common_parent = common_parent.substr(0, last_slash);
184+
CHECK(!common_parent.empty());
185+
}
186+
std::stringstream out;
187+
for (int i = 0; i < num_parents; i++) {
188+
out << "../";
189+
}
190+
out << absl::StripPrefix(path, common_parent);
191+
return out.str();
192+
}
193+
170194
} // namespace
171195

172196
bool FetcherConfig::add_cvd_file(const CvdFile& file, bool override_entry) {
@@ -221,7 +245,7 @@ Result<void> FetcherConfig::RemoveFileFromConfig(const std::string& path) {
221245
if (!dictionary_.isMember(kCvdFiles)) {
222246
return {};
223247
}
224-
std::string normalized = CF_EXPECT(NormalizePath(std::string(path)));
248+
std::string normalized = NormalizePath(std::string(path));
225249
auto& json_files = dictionary_[kCvdFiles];
226250
CF_EXPECTF(json_files.isMember(normalized), "Unknown file '{}'", normalized);
227251
json_files.removeMember(normalized);
@@ -232,19 +256,12 @@ Result<CvdFile> BuildFetcherConfigMember(FileSource purpose,
232256
const std::string& build_id,
233257
const std::string& build_target,
234258
const std::string& path,
235-
const std::string& directory_prefix) {
236-
std::string_view local_path(path);
237-
if (!android::base::ConsumePrefix(&local_path, directory_prefix)) {
238-
LOG(ERROR) << "Failed to remove prefix " << directory_prefix << " from "
239-
<< local_path;
240-
return {};
241-
}
242-
while (android::base::StartsWith(local_path, "/")) {
243-
android::base::ConsumePrefix(&local_path, "/");
244-
}
245-
std::string normalized = CF_EXPECT(NormalizePath(std::string(local_path)));
259+
const std::string& relative_dir) {
260+
std::string normalized = NormalizePath(path);
261+
std::string normalized_dir = NormalizePath(relative_dir);
262+
std::string relative_path = FindRelativePath(normalized, normalized_dir);
246263
// TODO(schuffelen): Do better for local builds here.
247-
return CvdFile(purpose, build_id, build_target, normalized);
264+
return CvdFile(purpose, build_id, build_target, relative_path);
248265
}
249266

250267
FetcherConfigs FetcherConfigs::Create(std::vector<FetcherConfig> configs) {

base/cvd/cuttlefish/host/libs/config/fetcher_config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ Result<CvdFile> BuildFetcherConfigMember(FileSource purpose,
8686
const std::string& build_id,
8787
const std::string& build_target,
8888
const std::string& path,
89-
const std::string& directory_prefix);
89+
const std::string& relative_dir);
9090

9191
class FetcherConfigs {
9292
public:

0 commit comments

Comments
 (0)