Recognize macOS extraction helper staging and verify release resources

This commit is contained in:
karl committed 2026-10-13 16:01:07 +02:00
1 parent f1028e2689
commit d41c5b5e98
4 files changed
+44 -4

No files matched your search

+10 -3
View File
@@ -53,10 +53,17 @@ def identity(path):
machine = struct.unpack_from('<H', signature, 4)[0] if signature[:4] == b'PE\0\0' else 0
arch = {0x8664: 'x86_64', 0xAA64: 'aarch64'}.get(machine)
platform = 'windows'
elif header[:6] == b'\x7fELF\x02\x01':
elif len(header) == 64 and header[:6] == b'\x7fELF\x02\x01':
machine = struct.unpack_from('<H', header, 18)[0]
arch = {62: 'x86_64', 183: 'aarch64'}.get(machine)
platform = 'linux'
elif len(header) >= 32 and header[:4] == b'\xcf\xfa\xed\xfe':
# Apple's mach_header_64: thin little-endian native executable.
cpu, _, filetype, commands, command_bytes = struct.unpack_from('<IIIII', header, 4)
if filetype != 2 or not 0 < commands <= 8192 or not commands * 8 <= command_bytes <= path.stat().st_size - 32:
raise ValueError('Invalid extraction Mach-O executable header')
arch = {0x01000007: 'x86_64', 0x0100000c: 'aarch64'}.get(cpu)
platform = 'macos'
else:
raise ValueError('Unsupported extraction executable format')
if arch is None:
@@ -106,7 +113,7 @@ def stage(binary, provenance, destination, root=ROOT):
try:
if target == name and hashlib.sha256(data).hexdigest() != record['sha256']:
raise ValueError('Extraction binary changed while staging')
if target == name and platform == 'linux':
if target == name and platform != 'windows':
temporary.chmod(0o755)
os.replace(temporary, destination / target)
finally:
@@ -119,7 +126,7 @@ def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--destination', type=Path, default=ROOT / 'apps/desktop/src-tauri/resources')
parser.add_argument('--verify-only', action='store_true')
parser.add_argument('--platform', choices=['windows', 'linux'], default='windows' if os.name == 'nt' else 'linux')
parser.add_argument('--platform', choices=['windows', 'linux', 'macos'], default='windows' if os.name == 'nt' else ('macos' if host_platform.system() == 'Darwin' else 'linux'))
parser.add_argument('--architecture', choices=['x86_64', 'aarch64'], default='aarch64' if host_platform.machine().lower() in {'aarch64', 'arm64'} else 'x86_64')
args = parser.parse_args()
if args.verify_only:
+20
View File
@@ -56,6 +56,26 @@ class ExtractionStageTests(unittest.TestCase):
worker.stage(binary, before, resources, root)
self.assertEqual((resources / 'searchi-extract-worker.exe').read_bytes(), binary.read_bytes())
def test_macos_thin_headers_and_staging(self):
import struct
for cpu, arch in [(0x01000007, 'x86_64'), (0x0100000c, 'aarch64')]:
with self.subTest(architecture=arch), tempfile.TemporaryDirectory() as directory:
root, binary, resources = self.fixture(directory)
data = struct.pack('<8I', 0xfeedfacf, cpu, 0, 2, 1, 8, 0, 0) + struct.pack('<2I', 0, 8)
binary.write_bytes(data)
worker.stage(binary, worker.fingerprint(root), resources, root)
records = worker.verify(resources, root, 'macos', arch)
self.assertIn('searchi-extract-worker', records)
for invalid in [data[:31], data[:12] + struct.pack('<I', 6) + data[16:], data[:4] + struct.pack('<I', 7) + data[8:], data[:20] + struct.pack('<I', 9999) + data[24:]]:
binary.write_bytes(invalid)
with self.assertRaises(ValueError):
worker.identity(binary)
def test_darwin_default_uses_macos_and_arm64(self):
with patch.object(worker.os, 'name', 'posix'), patch.object(worker.host_platform, 'system', return_value='Darwin'), patch.object(worker.host_platform, 'machine', return_value='arm64'), patch.object(worker, 'verify') as verify, patch('sys.argv', ['stage_extraction_worker.py', '--verify-only']):
worker.main()
self.assertEqual(verify.call_args.args[2:], ('macos', 'aarch64'))
def test_failed_build_never_stages_existing_binary(self):
with patch.object(worker.subprocess, 'run', side_effect=RuntimeError('cargo failed')), patch.object(worker, 'stage') as stage, patch('sys.argv', ['stage_extraction_worker.py']):
with self.assertRaises(RuntimeError):