@@ -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
172196bool 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
250267FetcherConfigs FetcherConfigs::Create (std::vector<FetcherConfig> configs) {
0 commit comments