Extract the `isLocatedUnderRootPath` check (#169)
Previously, we were incrementing the pointer with the first `res.second++`, so the next part of the if statement would see the character after that.
This extracts that code, fixes the issue and adds unit tests.
diff --git a/include/llbuild/BuildSystem/BuildSystem.h b/include/llbuild/BuildSystem/BuildSystem.h
index 0823eaa..2d91337 100644
--- a/include/llbuild/BuildSystem/BuildSystem.h
+++ b/include/llbuild/BuildSystem/BuildSystem.h
@@ -39,6 +39,8 @@
class BuildValue;
class Command;
class Tool;
+
+bool pathIsPrefixedByPath(std::string path, std::string prefixPath);
class BuildSystemDelegate {
// DO NOT COPY
diff --git a/lib/BuildSystem/BuildSystem.cpp b/lib/BuildSystem/BuildSystem.cpp
index 9f6565d..2965c94 100644
--- a/lib/BuildSystem/BuildSystem.cpp
+++ b/lib/BuildSystem/BuildSystem.cpp
@@ -2457,8 +2457,7 @@
// Check if the file is located under one of the allowed root paths.
for (auto root : roots) {
- auto res = std::mismatch(root.begin(), root.end(), fileToDelete.begin());
- if (res.first == root.end() && ((*(res.second++) == '\0') || (*(res.second++) == path_separator))) {
+ if (pathIsPrefixedByPath(fileToDelete, root)) {
isLocatedUnderRootPath = true;
}
}
@@ -2650,3 +2649,13 @@
void BuildSystem::resetForBuild() {
static_cast<BuildSystemImpl*>(impl)->resetForBuild();
}
+
+// This function checks if the given path is prefixed by another path.
+bool llbuild::buildsystem::pathIsPrefixedByPath(std::string path, std::string prefixPath) {
+ static char path_separator = llvm::sys::path::get_separator()[0];
+ auto res = std::mismatch(prefixPath.begin(), prefixPath.end(), path.begin());
+ // Check if `prefixPath` has been exhausted or just a separator remains.
+ bool isPrefix = res.first == prefixPath.end() || (*(res.first++) == path_separator);
+ // Check if `path` has been exhausted or just a separator remains.
+ return isPrefix && (res.second == path.end() || (*(res.second++) == path_separator));
+}
diff --git a/unittests/BuildSystem/BuildSystemTaskTests.cpp b/unittests/BuildSystem/BuildSystemTaskTests.cpp
index 4c932c0..7397774 100644
--- a/unittests/BuildSystem/BuildSystemTaskTests.cpp
+++ b/unittests/BuildSystem/BuildSystemTaskTests.cpp
@@ -776,4 +776,14 @@
ASSERT_FALSE(std::find(messages.begin(), messages.end(), "cannot remove stale file '" + linkFileList + "': No such file or directory") != messages.end());
}
+TEST(BuildSystemTaskTests, staleFileRemovalPathIsPrefixedByPath) {
+ ASSERT_TRUE(pathIsPrefixedByPath("/foo/bar", "/foo"));
+ ASSERT_TRUE(pathIsPrefixedByPath("/foo", "/foo"));
+ ASSERT_TRUE(pathIsPrefixedByPath("/foo/", "/foo"));
+ ASSERT_TRUE(pathIsPrefixedByPath("/foo", "/foo/"));
+
+ ASSERT_FALSE(pathIsPrefixedByPath("/bar", "/foo"));
+ ASSERT_FALSE(pathIsPrefixedByPath("/foobar", "/foo"));
+}
+
}