summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/buildtool/build_engine/target_map/utils.cpp6
-rw-r--r--test/buildtool/build_engine/target_map/target_map_internals.test.cpp16
-rwxr-xr-xtest/end-to-end/actions/conflicts.sh30
3 files changed, 52 insertions, 0 deletions
diff --git a/src/buildtool/build_engine/target_map/utils.cpp b/src/buildtool/build_engine/target_map/utils.cpp
index 4dcafa4f..ea3ce0a5 100644
--- a/src/buildtool/build_engine/target_map/utils.cpp
+++ b/src/buildtool/build_engine/target_map/utils.cpp
@@ -108,6 +108,12 @@ auto BuildMaps::Target::Utils::tree_conflict(const ExpressionPtr& map)
return ".";
}
auto p = std::filesystem::path{path};
+ if (p.is_absolute()) {
+ return p.string();
+ }
+ if (*p.begin() == "..") {
+ return p.string();
+ }
auto insert_result = blocked.insert(p);
if (not insert_result.second) {
return p.string(); // duplicate path
diff --git a/test/buildtool/build_engine/target_map/target_map_internals.test.cpp b/test/buildtool/build_engine/target_map/target_map_internals.test.cpp
index 72d5b59c..fa7aeca8 100644
--- a/test/buildtool/build_engine/target_map/target_map_internals.test.cpp
+++ b/test/buildtool/build_engine/target_map/target_map_internals.test.cpp
@@ -17,6 +17,22 @@ TEST_CASE("Tree conflicts", "[tree_conflict]") {
BuildMaps::Target::Utils::tree_conflict(root_overlap);
CHECK(root_overlap_conflict);
CHECK(*root_overlap_conflict == ".");
+
+ auto upwards_reference = Expression::FromJson(R"(
+ { "../foo.txt" : "content" })"_json);
+ REQUIRE(upwards_reference);
+ auto upwards_reference_conflict =
+ BuildMaps::Target::Utils::tree_conflict(upwards_reference);
+ CHECK(upwards_reference_conflict);
+ CHECK(*upwards_reference_conflict == "../foo.txt");
+
+ auto absolute_reference = Expression::FromJson(R"(
+ { "/foo.txt" : "content" })"_json);
+ REQUIRE(absolute_reference);
+ auto absolute_reference_conflict =
+ BuildMaps::Target::Utils::tree_conflict(absolute_reference);
+ CHECK(absolute_reference_conflict);
+ CHECK(*absolute_reference_conflict == "/foo.txt");
}
TEST_CASE("No conflict", "[tree_conflict]") {
diff --git a/test/end-to-end/actions/conflicts.sh b/test/end-to-end/actions/conflicts.sh
index 0adf0476..b0852ff5 100755
--- a/test/end-to-end/actions/conflicts.sh
+++ b/test/end-to-end/actions/conflicts.sh
@@ -18,6 +18,10 @@ cat > RULES <<'EOI'
, "key": "./foo.txt"
, "value": {"type": "BLOB", "data": "Same String"}
}
+ , { "type": "singleton_map"
+ , "key": "bar/baz/../../not-upwards.txt"
+ , "value": {"type": "BLOB", "data": "unrelated"}
+ }
]
}
]
@@ -185,6 +189,27 @@ cat > RULES <<'EOI'
, "body": {"type": "RESULT", "artifacts": {"type": "var", "name": "out"}}
}
}
+, "upwards-inputs":
+ { "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "map"
+ , { "type": "singleton_map"
+ , "key": "bar/../../foo.txt"
+ , "value": {"type": "BLOB", "data": "Some content"}
+ }
+ ]
+ , [ "out"
+ , { "type": "ACTION"
+ , "inputs": {"type": "var", "name": "map"}
+ , "outs": ["out"]
+ , "cmd": ["cp", "../foo.txt", "out"]
+ }
+ ]
+ ]
+ , "body": {"type": "RESULT", "artifacts": {"type": "var", "name": "out"}}
+ }
+ }
}
EOI
cat > TARGETS <<'EOI'
@@ -196,6 +221,7 @@ cat > TARGETS <<'EOI'
, "artifacts-tree-conflict": {"type": "artifacts-tree-conflict"}
, "runfiles-tree-conflict": {"type": "runfiles-tree-conflict"}
, "file-file-conflict": {"type": "file-file-conflict"}
+, "upwards-inputs": {"type": "upwards-inputs"}
}
EOI
@@ -231,4 +257,8 @@ echo
grep -i 'error.*.*conflict.*foo/bar/baz.txt' log
echo
+./bin/tool-under-test analyse -f log upwards-inputs 2>&1 && exit 1 || :
+grep -i 'error.*\.\./foo.txt' log
+
+echo
echo DONE