diff options
author | Joffrey F <joffrey@docker.com> | 2018-03-21 13:54:43 +0100 |
---|---|---|
committer | Joffrey F <joffrey@docker.com> | 2018-03-21 13:54:43 +0100 |
commit | 7f1be79b1aae33f888c7d523a1a94ec91f525185 (patch) | |
tree | fb02a9ff8635e53cd2168ab56b283f36b9ee9a00 | |
parent | 284c3d90d6ab1c49410d5622ca8cd3f37dcbe296 (diff) | |
download | docker-py-1953-tar-symlinks.tar.gz |
Don't descend into symlinks when building context tar1953-tar-symlinks
Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r-- | docker/utils/build.py | 2 | ||||
-rw-r--r-- | tests/unit/utils_test.py | 15 |
2 files changed, 16 insertions, 1 deletions
diff --git a/docker/utils/build.py b/docker/utils/build.py index 1622ec3..894b299 100644 --- a/docker/utils/build.py +++ b/docker/utils/build.py @@ -93,7 +93,7 @@ def walk(root, patterns, default=True): # Whether this file is implicitely included / excluded. matched = default if hit is None else hit sub = list(filter(lambda p: p[1], sub)) - if os.path.isdir(cur): + if os.path.isdir(cur) and not os.path.islink(cur): # Entirely skip directories if there are no chance any subfile will # be included. if all(not p[0] for p in sub) and not matched: diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py index 56800f9..00456e8 100644 --- a/tests/unit/utils_test.py +++ b/tests/unit/utils_test.py @@ -1058,6 +1058,21 @@ class TarTest(unittest.TestCase): assert tar_data.getnames() == ['th.txt'] assert tar_data.getmember('th.txt').mtime == -3600 + @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No symlinks on Windows') + def test_tar_directory_link(self): + dirs = ['a', 'b', 'a/c'] + files = ['a/hello.py', 'b/utils.py', 'a/c/descend.py'] + base = make_tree(dirs, files) + self.addCleanup(shutil.rmtree, base) + os.symlink(os.path.join(base, 'b'), os.path.join(base, 'a/c/b')) + with tar(base) as archive: + tar_data = tarfile.open(fileobj=archive) + names = tar_data.getnames() + for member in dirs + files: + assert member in names + assert 'a/c/b' in names + assert 'a/c/b/utils.py' not in names + class FormatEnvironmentTest(unittest.TestCase): def test_format_env_binary_unicode_value(self): |