diff options
| author | Anton Samarchyan <anton.samarchyan@savoirfairelinux.com> | 2016-12-28 15:20:24 -0500 |
|---|---|---|
| committer | Tim Graham <timograham@gmail.com> | 2016-12-28 19:14:58 -0500 |
| commit | 5cf4894836bd537161df467890d9b986678a7937 (patch) | |
| tree | 0ae370e4ad23c00e02943814daa2e99fdd0aaaec /django/utils/archive.py | |
| parent | 4579c3f6b8d3a5ebd6c570836cd0552892eb0d61 (diff) | |
Fixed #27628 -- Fixed unarchiving a file without permission data.
Diffstat (limited to 'django/utils/archive.py')
| -rw-r--r-- | django/utils/archive.py | 17 |
1 files changed, 14 insertions, 3 deletions
diff --git a/django/utils/archive.py b/django/utils/archive.py index f8c1a0f83b..57e87658a6 100644 --- a/django/utils/archive.py +++ b/django/utils/archive.py @@ -23,6 +23,7 @@ THE SOFTWARE. """ import os import shutil +import stat import tarfile import zipfile @@ -98,6 +99,16 @@ class BaseArchive(object): """ Base Archive class. Implementations should inherit this class. """ + @staticmethod + def _copy_permissions(mode, filename): + """ + If the file in the archive has some permissions (this assumes a file + won't be writable/executable without being readable), apply those + permissions to the unarchived file. + """ + if mode & stat.S_IROTH: + os.chmod(filename, mode) + def split_leading_dir(self, path): path = str(path) path = path.lstrip('/').lstrip('\\') @@ -164,7 +175,7 @@ class TarArchive(BaseArchive): os.makedirs(dirname) with open(filename, 'wb') as outfile: shutil.copyfileobj(extracted, outfile) - os.chmod(filename, member.mode) + self._copy_permissions(member.mode, filename) finally: if extracted: extracted.close() @@ -200,9 +211,9 @@ class ZipArchive(BaseArchive): else: with open(filename, 'wb') as outfile: outfile.write(data) - # convert ZipInfo.external_attr to mode + # Convert ZipInfo.external_attr to mode mode = info.external_attr >> 16 - os.chmod(filename, mode) + self._copy_permissions(mode, filename) def close(self): self._archive.close() |
