diff options
author | Joffrey F <f.joffrey@gmail.com> | 2018-01-29 19:11:23 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-29 19:11:23 -0800 |
commit | de88ab39c0321b9c68fc6c707fcc804b72a82eca (patch) | |
tree | 7685f84cec9eb078bcfe442ead472f2697d4c0c2 | |
parent | 4ff296247b4ed9c4afbb0b5293bd4deecb4fe708 (diff) | |
parent | 4e34300379a9d85d99192e890cef2f1f656c6761 (diff) | |
download | docker-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.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() |