#!/usr/bin/env python3 """Build an independently downloadable Quest conversion runtime.""" import argparse import gzip import hashlib import json import pathlib import shutil import struct import subprocess import tarfile import tempfile import zipfile CLI_VERSION = '1.2.3' LIBRARIES_VERSION = '3.4.3-23204ea' CLI_SHA256 = '307d58a69a5c9722f912d1b6566b0dd1e0ebe1440c6d1e56cab6cb883d74fef2' LIBRARIES_SHA256 = '6cec6c176e1aeee8d9ec4f9b4e3982f71da7b44a36a293249620073a06f00e5e' SOURCE_SHA256 = '2db2c0f597a8be01d9742180019627b4c23fd0213f04f5034fbad53f0d296eb3' FRAMEBRIDGE_COMMIT = '80ef9ca6a77eed1ca6b2cc6f746d9897e4178b4e' FRAMEBRIDGE_SOURCE_SHA256 = 'ea90ea8dd2f0fe49d54d2df5cc61c1876c9562e55fb40fce2651b1d5594dab7c' FRAMEBRIDGE_ABIS = {'arm64-v8a': 183, 'armeabi-v7a': 40} def digest(path): with path.open('rb') as source: return hashlib.file_digest(source, 'sha256').hexdigest() def safe_zip_extract(source, destination): with zipfile.ZipFile(source) as archive: for entry in archive.infolist(): path = pathlib.PurePosixPath(entry.filename) if (path.is_absolute() or '..' in path.parts or '\\' in entry.filename or (entry.external_attr >> 16) & 0o170000 == 0o120000): raise ValueError('Unsafe OVR Port library entry') target = destination.joinpath(*path.parts) if entry.is_dir(): target.mkdir(parents=True, exist_ok=True) else: target.parent.mkdir(parents=True, exist_ok=True) with archive.open(entry) as data, target.open('xb') as output: shutil.copyfileobj(data, output) def framebridge_source(source, destination): """Ship the exact adapter source and its build instructions with the runtime.""" prefix = f'frameport-{FRAMEBRIDGE_COMMIT}/' fixed = {'LICENSE', 'THIRD_PARTY_NOTICES.md', 'native/README.md', 'native/build.py'} with tarfile.open(source, 'r:gz') as upstream, destination.open('wb') as output, \ gzip.GzipFile(filename='', mode='wb', fileobj=output, mtime=0) as compressed, \ tarfile.open(fileobj=compressed, mode='w') as selected: files = [m for m in upstream.getmembers() if m.name.startswith(prefix) and (m.name[len(prefix):] in fixed or m.name[len(prefix):].startswith('native/adapter/')) and m.isfile()] if not fixed.issubset({m.name[len(prefix):] for m in files}) or len(files) > 100: raise ValueError('Incomplete FrameBridge corresponding source') for member in sorted(files, key=lambda m: m.name): relative = member.name[len(prefix):] if member.size > 2 * 1024 * 1024 or '..' in pathlib.PurePosixPath(relative).parts: raise ValueError('Invalid FrameBridge source entry') copy = tarfile.TarInfo(f'framebridge/{relative}') copy.size, copy.mode, copy.mtime = member.size, 0o644, 0 selected.addfile(copy, upstream.extractfile(member)) def install_framebridge(payload, source, adapters): if digest(source) != FRAMEBRIDGE_SOURCE_SHA256: raise ValueError('Pinned FrameBridge source checksum mismatch') with tarfile.open(source, 'r:gz') as upstream: license_file = upstream.extractfile(f'frameport-{FRAMEBRIDGE_COMMIT}/LICENSE') if license_file is None: raise ValueError('FrameBridge license missing') (payload / 'FRAMEBRIDGE_LICENSE').write_bytes(license_file.read()) framebridge_source(source, payload / 'FRAMEBRIDGE_SOURCE.tar.gz') (payload / 'FRAMEBRIDGE_SOURCE').write_text( f'https://github.com/spoopyghosty0/frameport/tree/{FRAMEBRIDGE_COMMIT}\n') for abi, machine in FRAMEBRIDGE_ABIS.items(): adapter = pathlib.Path(adapters[abi]) data = adapter.read_bytes() elf_class = 2 if abi == 'arm64-v8a' else 1 if (len(data) < 1024 or data[:6] != b'\x7fELF' + bytes((elf_class, 1)) or struct.unpack_from('