From f1a4504aae8f33b7deb660b1d86299101c87614a Mon Sep 17 00:00:00 2001 From: Vadim Lebedev Date: Thu, 11 Aug 2022 18:17:17 +0200 Subject: [PATCH] Fix creation of password protected ZIP files --- libarchive/__init__.py | 4 ++++ libarchive/zip.py | 23 +++++++++++++++++++---- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/libarchive/__init__.py b/libarchive/__init__.py index df8c115..2ea051a 100644 --- a/libarchive/__init__.py +++ b/libarchive/__init__.py @@ -499,6 +499,9 @@ class Archive(object): def __del__(self): self.close() + def set_initila_options(self): + pass + def init(self): if self.mode == 'r': self._a = _libarchive.archive_read_new() @@ -506,6 +509,7 @@ class Archive(object): self._a = _libarchive.archive_write_new() self.format_func(self._a) self.filter_func(self._a) + self.set_initila_options() if self.mode == 'r': if self.password: self.add_passphrase(self.password) diff --git a/libarchive/zip.py b/libarchive/zip.py index be65386..e19b4f6 100644 --- a/libarchive/zip.py +++ b/libarchive/zip.py @@ -1,5 +1,5 @@ import os, time -from libarchive import is_archive, Entry, SeekableArchive +from libarchive import is_archive, Entry, SeekableArchive, _libarchive from zipfile import ZIP_STORED, ZIP_DEFLATED @@ -60,19 +60,34 @@ class ZipEntry(Entry): CRC = property(_get_missing, _set_missing) compress_size = property(_get_missing, _set_missing) - +# encryption is one of (traditional = zipcrypt, aes128, aes256) class ZipFile(SeekableArchive): - def __init__(self, f, mode='r', compression=ZIP_DEFLATED, allowZip64=False, password=None): + def __init__(self, f, mode='r', compression=ZIP_DEFLATED, allowZip64=False, password=None, + encryption=None): super(ZipFile, self).__init__( f, mode=mode, format='zip', entry_class=ZipEntry, encoding='CP437', password=password ) + self.compression = compression + self.encryption = encryption if mode == 'w' and compression == ZIP_STORED: # Disable compression for writing. _libarchive.archive_write_set_format_option(self.archive._a, "zip", "compression", "store") - self.compression = compression + getinfo = SeekableArchive.getentry + def set_initial_options(self): + if self.mode == 'w' and self.compression == ZIP_STORED: + # Disable compression for writing. + _libarchive.archive_write_set_format_option(self.archive._a, "zip", "compression", "store") + + if self.mode == 'w' and self.password: + if not self.encryption: + self.encryption = "traditional" + _libarchive.archive_write_set_format_option(self._a, "zip", "encryption", self.encryption) + + + def namelist(self): return list(self.iterpaths())