From 4d3037de1e8ded8e748440131d2e10fab149f547 Mon Sep 17 00:00:00 2001 From: Wouter Wijsman Date: Thu, 2 Jan 2020 00:23:52 +0100 Subject: [PATCH 1/2] Preserve permissions on UNIX(based/like) systems The reasoning behind this is that the unzip command (Info-ZIP) on pretty much every unix system will preserve the permissions by default. The Info-ZIP unzip command is shipped with all currently supported versions of: - MacOS - OpenBSD and NetBSD - Probably every manjor Linux distribution Here is a list: https://pkgs.org/download/unzip --- Lib/zipfile.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/Lib/zipfile.py b/Lib/zipfile.py index e1d07f2a5237bb7..fcfced35200b8e7 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -1677,14 +1677,24 @@ def _extract_member(self, member, targetpath, pwd): if upperdirs and not os.path.exists(upperdirs): os.makedirs(upperdirs) + # Extract the member if member.is_dir(): if not os.path.isdir(targetpath): os.mkdir(targetpath) - return targetpath - - with self.open(member, pwd=pwd) as source, \ - open(targetpath, "wb") as target: - shutil.copyfileobj(source, target) + else: + with self.open(member, pwd=pwd) as source, \ + open(targetpath, "wb") as target: + shutil.copyfileobj(source, target) + + # Preserve the permissions if we're on a posix system and the create_system was UNIX + # In the zip specification create_system 3 is UNIX + # See https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT CHAPTER 4.4.2.2 + zip_create_system_unix = 3 + if member.create_system == zip_create_system_unix and os.name == "posix": + # The first 16 bits contain the UNIX permission attributes + # See https://stackoverflow.com/a/46837272 + attr = member.external_attr >> 16 + os.chmod(targetpath, attr) return targetpath From 30189d4698fac8d763e54407b971241eacb2cff3 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Tue, 3 Mar 2020 13:50:38 +0000 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NEWS.d/next/Library/2020-03-03-13-50-37.bpo-15795.qQkxN0.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2020-03-03-13-50-37.bpo-15795.qQkxN0.rst diff --git a/Misc/NEWS.d/next/Library/2020-03-03-13-50-37.bpo-15795.qQkxN0.rst b/Misc/NEWS.d/next/Library/2020-03-03-13-50-37.bpo-15795.qQkxN0.rst new file mode 100644 index 000000000000000..6a8f1ae5aea7832 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2020-03-03-13-50-37.bpo-15795.qQkxN0.rst @@ -0,0 +1 @@ +Preserve permissions when extracting zip files on POSIX systems. Only do so if the zip file was created on a Unix-like system. \ No newline at end of file