diff options
-rw-r--r-- | docker/utils/utils.py | 3 | ||||
-rw-r--r-- | tests/unit/utils_test.py | 26 |
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() |