mirror of
https://github.com/veracrypt/VeraCrypt.git
synced 2026-06-17 01:56:10 -05:00
Linux: Support legacy Python for reproducible build
Allow reproducible makeself finalization to run with Python 2.6+ or Python 3 by avoiding Python 3-only syntax and probing python3, python, then python2.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (c) 2026 VeraCrypt
|
||||
# Governed by the Apache License 2.0.
|
||||
@@ -14,6 +14,8 @@
|
||||
# CRCsum makes its extractor skip the redundant CRC check.
|
||||
# - MD5 is recomputed, which the extractor still verifies.
|
||||
#
|
||||
# Compatible with Python >= 2.6 and Python 3.
|
||||
#
|
||||
# Usage: makeself_repro_finalize.py <archive>
|
||||
|
||||
import hashlib
|
||||
@@ -23,28 +25,27 @@ import sys
|
||||
|
||||
def finalize(path):
|
||||
with open(path, "rb") as f:
|
||||
raw = bytearray(f.read())
|
||||
text = raw.decode("latin1", errors="replace")
|
||||
raw = f.read()
|
||||
text = raw.decode("latin1")
|
||||
# Locate payload start by line count, mirroring makeself's own extractor.
|
||||
m = re.search(r'^skip="(\d+)"', text, re.MULTILINE)
|
||||
if not m:
|
||||
sys.exit(f"{path}: no skip= line in makeself header")
|
||||
sys.exit("%s: no skip= line in makeself header" % path)
|
||||
skip = int(m.group(1))
|
||||
header_text = "\n".join(text.split("\n")[:skip]) + "\n"
|
||||
offset = len(header_text.encode("latin1"))
|
||||
if bytes(raw[offset:offset + 3]) != b"\x1f\x8b\x08":
|
||||
sys.exit(f"{path}: no gzip magic at payload offset {offset}")
|
||||
if raw[offset:offset + 3] != b"\x1f\x8b\x08":
|
||||
sys.exit("%s: no gzip magic at payload offset %d" % (path, offset))
|
||||
# gzip header mtime: 4-byte LE uint at offset+4 (RFC 1952 section 2.3.1).
|
||||
raw[offset + 4:offset + 8] = b"\x00\x00\x00\x00"
|
||||
payload = bytes(raw[offset:])
|
||||
payload = raw[offset:offset + 4] + b"\x00\x00\x00\x00" + raw[offset + 8:]
|
||||
new_md5 = hashlib.md5(payload).hexdigest()
|
||||
# CRCsum -> all zeros (extractor then skips the CRC check); MD5 -> fresh.
|
||||
new_header = re.sub(r'CRCsum="[^"]*"', 'CRCsum="0000000000"', header_text)
|
||||
new_header = re.sub(r'MD5="[0-9a-fA-F]+"', f'MD5="{new_md5}"', new_header)
|
||||
new_header = re.sub(r'MD5="[0-9a-fA-F]+"', 'MD5="%s"' % new_md5, new_header)
|
||||
new_bytes = new_header.encode("latin1")
|
||||
# Line count must stay the same so makeself's "skip=" remains accurate.
|
||||
if new_bytes.count(b"\n") != skip:
|
||||
sys.exit(f"{path}: header line count changed during rewrite")
|
||||
sys.exit("%s: header line count changed during rewrite" % path)
|
||||
with open(path, "wb") as f:
|
||||
f.write(new_bytes + payload)
|
||||
|
||||
|
||||
+5
-4
@@ -319,6 +319,7 @@ TAR_DETERMINISTIC := $(strip $(shell t=$$(mktemp 2>/dev/null) && tar --sor
|
||||
GZIP_NO_TIMESTAMP := $(strip $(shell printf x | gzip -n -c >/dev/null 2>&1 && echo yes))
|
||||
MAKESELF_PACKAGING_DATE := $(strip $(shell makeself --help 2>&1 | grep -q -- '--packaging-date' && echo yes))
|
||||
MAKESELF_TAR_EXTRA := $(strip $(shell makeself --help 2>&1 | grep -q -- '--tar-extra' && echo yes))
|
||||
PYTHON_REPRO_FINALIZE := $(strip $(shell for p in python3 python python2; do command -v $$p >/dev/null 2>&1 || continue; $$p -c 'import sys; v=sys.version_info; sys.exit(not (v[0] > 2 or (v[0] == 2 and v[1] >= 6)))' >/dev/null 2>&1 && command -v $$p && break; done))
|
||||
|
||||
INSTALL_UNINSTALLER ?= 1
|
||||
INSTALL_LICENSE ?= 1
|
||||
@@ -631,11 +632,11 @@ endif
|
||||
# makeself runs 'gzip -c9 < tmpfile' which writes tmpfile's mtime into
|
||||
# the gzip header (SOURCE_DATE_EPOCH is ignored for redirected stdin).
|
||||
# Zero the mtime and refresh CRCsum/MD5; installer --check still passes.
|
||||
@if command -v python3 >/dev/null 2>&1; then \
|
||||
python3 $(BASE_DIR)/Build/Tools/makeself_repro_finalize.py \
|
||||
$(BASE_DIR)/Setup/Linux/$(INSTALLER_NAME); \
|
||||
@if [ -n "$(PYTHON_REPRO_FINALIZE)" ]; then \
|
||||
"$(PYTHON_REPRO_FINALIZE)" "$(BASE_DIR)/Build/Tools/makeself_repro_finalize.py" \
|
||||
"$(BASE_DIR)/Setup/Linux/$(INSTALLER_NAME)"; \
|
||||
else \
|
||||
echo "Reproducible build: python3 unavailable, skipping makeself finalize"; \
|
||||
echo "Reproducible build: Python 2.6+ unavailable, skipping makeself finalize"; \
|
||||
fi
|
||||
|
||||
appimage: prepare
|
||||
|
||||
Reference in New Issue
Block a user