summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoffrey F <f.joffrey@gmail.com>2018-01-29 19:11:23 -0800
committerGitHub <noreply@github.com>2018-01-29 19:11:23 -0800
commitde88ab39c0321b9c68fc6c707fcc804b72a82eca (patch)
tree7685f84cec9eb078bcfe442ead472f2697d4c0c2
parent4ff296247b4ed9c4afbb0b5293bd4deecb4fe708 (diff)
parent4e34300379a9d85d99192e890cef2f1f656c6761 (diff)
downloaddocker-py-de88ab39c0321b9c68fc6c707fcc804b72a82eca.tar.gz
Merge pull request #1880 from docker/1841-tar-broken-symlinks
Do not break when archiving broken symlinks
-rw-r--r--docker/utils/utils.py3
-rw-r--r--tests/unit/utils_test.py26
2 files changed, 28 insertions, 1 deletions
diff --git a/docker/utils/utils.py b/docker/utils/utils.py
index 2de995c..c4db175 100644
--- a/docker/utils/utils.py
+++ b/docker/utils/utils.py
@@ -98,7 +98,8 @@ def create_archive(root, files=None, fileobj=None, gzip=False):
files = build_file_list(root)
for path in files:
full_path = os.path.join(root, path)
- if not os.access(full_path, os.R_OK):
+
+ if os.lstat(full_path).st_mode & os.R_OK == 0:
raise IOError(
'Can not access file in context: {}'.format(full_path)
)
diff --git a/tests/unit/utils_test.py b/tests/unit/utils_test.py
index 2fa1d05..8674e85 100644
--- a/tests/unit/utils_test.py
+++ b/tests/unit/utils_test.py
@@ -948,6 +948,20 @@ class TarTest(unittest.TestCase):
tar_data = tarfile.open(fileobj=archive)
self.assertEqual(sorted(tar_data.getnames()), ['bar', 'foo'])
+ @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No chmod on Windows')
+ def test_tar_with_inaccessible_file(self):
+ base = tempfile.mkdtemp()
+ full_path = os.path.join(base, 'foo')
+ self.addCleanup(shutil.rmtree, base)
+ with open(full_path, 'w') as f:
+ f.write('content')
+ os.chmod(full_path, 0o222)
+ with pytest.raises(IOError) as ei:
+ tar(base)
+
+ assert 'Can not access file in context: {}'.format(full_path) in \
+ ei.exconly()
+
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No symlinks on Windows')
def test_tar_with_file_symlinks(self):
base = tempfile.mkdtemp()
@@ -975,6 +989,18 @@ class TarTest(unittest.TestCase):
sorted(tar_data.getnames()), ['bar', 'bar/foo', 'foo']
)
+ @pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No symlinks on Windows')
+ def test_tar_with_broken_symlinks(self):
+ base = tempfile.mkdtemp()
+ self.addCleanup(shutil.rmtree, base)
+ for d in ['foo', 'bar']:
+ os.makedirs(os.path.join(base, d))
+
+ os.symlink('../baz', os.path.join(base, 'bar/foo'))
+ with tar(base) as archive:
+ tar_data = tarfile.open(fileobj=archive)
+ assert sorted(tar_data.getnames()) == ['bar', 'bar/foo', 'foo']
+
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='No UNIX sockets on Win32')
def test_tar_socket_file(self):
base = tempfile.mkdtemp()