Fixed #26494 -- Made Archive.extract() preserve file permissions.
This commit is contained in:
parent
dd99e69fa8
commit
d0112cf930
|
@ -164,6 +164,7 @@ class TarArchive(BaseArchive):
|
||||||
os.makedirs(dirname)
|
os.makedirs(dirname)
|
||||||
with open(filename, 'wb') as outfile:
|
with open(filename, 'wb') as outfile:
|
||||||
shutil.copyfileobj(extracted, outfile)
|
shutil.copyfileobj(extracted, outfile)
|
||||||
|
os.chmod(filename, member.mode)
|
||||||
finally:
|
finally:
|
||||||
if extracted:
|
if extracted:
|
||||||
extracted.close()
|
extracted.close()
|
||||||
|
@ -185,6 +186,7 @@ class ZipArchive(BaseArchive):
|
||||||
leading = self.has_leading_dir(namelist)
|
leading = self.has_leading_dir(namelist)
|
||||||
for name in namelist:
|
for name in namelist:
|
||||||
data = self._archive.read(name)
|
data = self._archive.read(name)
|
||||||
|
info = self._archive.getinfo(name)
|
||||||
if leading:
|
if leading:
|
||||||
name = self.split_leading_dir(name)[1]
|
name = self.split_leading_dir(name)[1]
|
||||||
filename = os.path.join(to_path, name)
|
filename = os.path.join(to_path, name)
|
||||||
|
@ -198,6 +200,9 @@ class ZipArchive(BaseArchive):
|
||||||
else:
|
else:
|
||||||
with open(filename, 'wb') as outfile:
|
with open(filename, 'wb') as outfile:
|
||||||
outfile.write(data)
|
outfile.write(data)
|
||||||
|
# convert ZipInfo.external_attr to mode
|
||||||
|
mode = info.external_attr >> 16
|
||||||
|
os.chmod(filename, mode)
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self._archive.close()
|
self._archive.close()
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,5 +1,7 @@
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
import stat
|
||||||
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
@ -42,6 +44,14 @@ class ArchiveTester(object):
|
||||||
extract(self.archive_path, self.tmpdir)
|
extract(self.archive_path, self.tmpdir)
|
||||||
self.check_files(self.tmpdir)
|
self.check_files(self.tmpdir)
|
||||||
|
|
||||||
|
@unittest.skipIf(sys.platform == 'win32', 'Python on Windows has a limited os.chmod().')
|
||||||
|
def test_extract_file_permissions(self):
|
||||||
|
"""Archive.extract() preserves file permissions."""
|
||||||
|
extract(self.archive_path, self.tmpdir)
|
||||||
|
filepath = os.path.join(self.tmpdir, 'executable')
|
||||||
|
# The file has executable permission.
|
||||||
|
self.assertTrue(os.stat(filepath).st_mode & stat.S_IXOTH)
|
||||||
|
|
||||||
def test_extract_function_with_leadpath(self):
|
def test_extract_function_with_leadpath(self):
|
||||||
extract(self.archive_lead_path, self.tmpdir)
|
extract(self.archive_lead_path, self.tmpdir)
|
||||||
self.check_files(self.tmpdir)
|
self.check_files(self.tmpdir)
|
||||||
|
|
Loading…
Reference in New Issue