This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author obfusk
Recipients christian.heimes, eighthave, jondo, obfusk
Date 2021-06-22.13:49:25
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1624369765.97.0.465081757807.issue43547@roundup.psfhosted.org>
In-reply-to
Content
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
History
Date User Action Args
2021-06-22 13:49:26obfusksetrecipients: + obfusk, christian.heimes, jondo, eighthave
2021-06-22 13:49:25obfusksetmessageid: <1624369765.97.0.465081757807.issue43547@roundup.psfhosted.org>
2021-06-22 13:49:25obfusklinkissue43547 messages
2021-06-22 13:49:25obfuskcreate