diff options
-rw-r--r-- | src/buildtool/build_engine/target_map/utils.cpp | 6 | ||||
-rw-r--r-- | test/buildtool/build_engine/target_map/target_map_internals.test.cpp | 16 | ||||
-rwxr-xr-x | test/end-to-end/actions/conflicts.sh | 30 |
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 |