Skip to content

Commit

Permalink
merge_tree: proper check for subdirectory
Browse files Browse the repository at this point in the history
  • Loading branch information
woutdenolf committed Aug 22, 2023
1 parent b2cb091 commit f86cee9
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 6 deletions.
15 changes: 12 additions & 3 deletions conda_build/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -715,6 +715,17 @@ def copytree(src, dst, symlinks=False, ignore=None, dry_run=False):
return dst_lst


def is_subdir(child, parent, strict = True):
"""
Check whether child is a (strict) subdirectory if parent.
"""
parent = Path(parent).resolve()
child = Path(child).resolve()
if strict:
return parent in child.parents
return child == parent or parent in child.parents


def merge_tree(
src, dst, symlinks=False, timeout=900, lock=None, locking=True, clobber=False
):
Expand All @@ -725,9 +736,7 @@ def merge_tree(
Like copytree(src, dst), but raises an error if merging the two trees
would overwrite any files.
"""
dst = os.path.normpath(os.path.normcase(dst))
src = os.path.normpath(os.path.normcase(src))
assert not dst.startswith(src), (
assert not is_subdir(dst, src, strict=False), (
"Can't merge/copy source into subdirectory of itself. "
"Please create separate spaces for these things.\n"
" src: {}\n"
Expand Down
27 changes: 24 additions & 3 deletions tests/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,32 @@ def test_disallow_merge_conflicts(namespace_setup: os.PathLike):


@pytest.mark.sanity
def test_disallow_in_tree_merge(testing_workdir):
with open("testfile", "w") as f:
def test_is_subdir(testing_workdir):
assert not utils.is_subdir(testing_workdir, testing_workdir)
assert utils.is_subdir(testing_workdir, testing_workdir, strict=False)
subdir = os.path.join(testing_workdir, "subdir")
assert utils.is_subdir(subdir, testing_workdir)
assert utils.is_subdir(subdir, testing_workdir, strict=False)


@pytest.mark.sanity
def test_disallow_down_tree_merge(testing_workdir):
src = testing_workdir
with open(os.path.join(src,"testfile"), "w") as f:
f.write("test")
with pytest.raises(AssertionError):
utils.merge_tree(testing_workdir, os.path.join(testing_workdir, "subdir"))
utils.merge_tree(src, testing_workdir)
with pytest.raises(AssertionError):
utils.merge_tree(src, os.path.join(testing_workdir, "subdir"))


@pytest.mark.sanity
def test_allow_up_tree_merge(testing_workdir):
src = os.path.join(testing_workdir, "subdir")
os.makedirs(src)
with open(os.path.join(src,"testfile"), "w") as f:
f.write("test")
utils.merge_tree(src, testing_workdir)


def test_relative_default():
Expand Down

0 comments on commit f86cee9

Please sign in to comment.