From 999d27748c7fb5cd3cfafe163ef9255e4d8458fe Mon Sep 17 00:00:00 2001 From: Jonathan <15150702+jonnyhsu@users.noreply.github.com> Date: Thu, 26 Mar 2020 19:16:49 -0600 Subject: [PATCH 1/4] Check if symlink exists before creating --- Lib/tarfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Lib/tarfile.py b/Lib/tarfile.py index e2b60532f693d4..7311fa1613c61e 100755 --- a/Lib/tarfile.py +++ b/Lib/tarfile.py @@ -2232,6 +2232,8 @@ def makelink(self, tarinfo, targetpath): try: # For systems that support symbolic and hard links. if tarinfo.issym(): + if os.path.lexists(targetpath): + os.unlink(targetpath) os.symlink(tarinfo.linkname, targetpath) else: # See extract(). From 905b6c72b996c6de1c863d61e180f7f2ca1777f3 Mon Sep 17 00:00:00 2001 From: Jonathan <15150702+jonnyhsu@users.noreply.github.com> Date: Fri, 27 Mar 2020 21:01:08 -0600 Subject: [PATCH 2/4] Add news entry for bpo-40049 --- .../next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst diff --git a/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst b/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst new file mode 100644 index 00000000000000..47c7f2e3f45b8e --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst @@ -0,0 +1,3 @@ +The tarfile module now checks for an existing symlink before creating a +new one during extraction. This prevents premature scanning of the +archive and errors when extracting from a stream. From 083f85e7f9cf1a3055af21c3da265722a5a03629 Mon Sep 17 00:00:00 2001 From: Jonathan Hsu <15150702+jonnyhsu@users.noreply.github.com> Date: Sat, 6 Jun 2020 14:21:17 -0600 Subject: [PATCH 3/4] Add unit test for bpo-40049 --- Lib/test/test_tarfile.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Lib/test/test_tarfile.py b/Lib/test/test_tarfile.py index cae96802ded67e..54916c47d6bb70 100644 --- a/Lib/test/test_tarfile.py +++ b/Lib/test/test_tarfile.py @@ -755,6 +755,18 @@ def test_compare_members(self): finally: tar1.close() + @support.skip_unless_symlink + def test_symlink_overwrite(self): + # Test for issue #40049: Extracting a symlink over an existing file + # in stream mode causes a backwards seek + sympath = os.path.join(TEMPDIR, 'symtype2') + pathlib.Path(sympath).touch() + try: + self.tar.extract('symtype2', TEMPDIR) + self.assertTrue(os.path.islink(sympath)) + finally: + pathlib.Path(sympath).unlink(missing_ok=True) + class GzipStreamReadTest(GzipTest, StreamReadTest): pass From 5eb7e21bb4a35b30e1ba4b7dd4eb048eddf4c07d Mon Sep 17 00:00:00 2001 From: Jonathan Hsu <15150702+jonnyhsu@users.noreply.github.com> Date: Sat, 6 Jun 2020 14:38:10 -0600 Subject: [PATCH 4/4] Update Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst Co-authored-by: Zackery Spytz --- .../next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst b/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst index 47c7f2e3f45b8e..48cca7e5c0787d 100644 --- a/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst +++ b/Misc/NEWS.d/next/Library/2020-03-27-20-49-32.bpo-40049.8079ca.rst @@ -1,3 +1,3 @@ -The tarfile module now checks for an existing symlink before creating a +The :mod:`tarfile` module now checks for an existing symlink before creating a new one during extraction. This prevents premature scanning of the archive and errors when extracting from a stream.