[issue43547] support ZIP files with zeroed out fields (e.g. for reproducible builds)
Felix C. Stegerman
report at bugs.python.org
Tue Jun 22 09:49:25 EDT 2021
Felix C. Stegerman <flx at obfusk.net> added the comment:
https://github.com/obfusk/apksigcopier currently produces reproducible ZIP files identical to those produced by apksigner using this code:
DATETIMEZERO = (1980, 0, 0, 0, 0, 0)
class ReproducibleZipInfo(zipfile.ZipInfo):
"""Reproducible ZipInfo hack."""
_override = {} # type: Dict[str, Any]
def __init__(self, zinfo, **override):
if override:
self._override = {**self._override, **override}
for k in self.__slots__:
if hasattr(zinfo, k):
setattr(self, k, getattr(zinfo, k))
def __getattribute__(self, name):
if name != "_override":
try:
return self._override[name]
except KeyError:
pass
return object.__getattribute__(self, name)
class APKZipInfo(ReproducibleZipInfo):
"""Reproducible ZipInfo for APK files."""
_override = dict(
compress_type=8,
create_system=0,
create_version=20,
date_time=DATETIMEZERO,
external_attr=0,
extract_version=20,
flag_bits=0x800,
)
def patch_meta(...):
...
with zipfile.ZipFile(output_apk, "a") as zf_out:
info_data = [(APKZipInfo(info, date_time=date_time), data)
for info, data in extracted_meta]
_write_to_zip(info_data, zf_out)
if sys.version_info >= (3, 7):
def _write_to_zip(info_data, zf_out):
for info, data in info_data:
zf_out.writestr(info, data, compresslevel=9)
else:
def _write_to_zip(info_data, zf_out):
old = zipfile._get_compressor
zipfile._get_compressor = lambda _: zlib.compressobj(9, 8, -15)
try:
for info, data in info_data:
zf_out.writestr(info, data)
finally:
zipfile._get_compressor = old
----------
_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue43547>
_______________________________________
More information about the Python-bugs-list
mailing list