#!/usr/bin/env python3 """Compare the pinned toml++ source archive with installed development inputs.""" import argparse import hashlib import json from pathlib import Path import tarfile ROOT = Path(__file__).resolve().parents[2] parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('--output', type=Path, required=True) args = parser.parse_args() pin = json.loads(Path(__file__).with_name('pins.json').read_text())['tomlplusplus'] archive = ROOT / '.deps/source-archives' / pin['name'] data = archive.read_bytes() if len(data) > pin['maximumBytes'] or any(hashlib.new(name, data).hexdigest() != expected for name, expected in pin['hashes'].items()): raise SystemExit('Archive does not match the recipe checksums') headers, license_text = [], None with tarfile.open(archive) as stream: for member in stream: if not member.isfile(): continue prefix = 'tomlplusplus-3.4.0/' if not member.name.startswith(prefix) or '..' in Path(member.name).parts: raise SystemExit('Unexpected source member path') relative = member.name[len(prefix):] if not (relative.startswith('include/toml++/') or relative == 'LICENSE'): continue if member.size > 8 * 1024 * 1024: raise SystemExit('Selected source file exceeds its limit') content = stream.extractfile(member).read() if relative == 'LICENSE': license_text = content else: installed = Path('/usr') / relative headers.append({'path': relative, 'bytes': len(content), 'sha256': hashlib.sha256(content).hexdigest(), 'installedMatches': installed.is_file() and installed.read_bytes() == content}) if license_text is None or len(headers) != 51 or not all(row['installedMatches'] for row in headers): raise SystemExit('Installed header set differs from the pinned source archive') record = {'archive': str(archive.relative_to(ROOT)), 'sha256': hashlib.sha256(data).hexdigest(), 'headers': headers, 'allInstalledHeadersMatch': True, 'headerCount': len(headers), 'licenseSha256': hashlib.sha256(license_text).hexdigest(), 'licenseMatchesInstalled': license_text == Path('/usr/share/licenses/tomlplusplus/LICENSE').read_bytes(), 'scope': 'Source archive and current installed headers; not a rebuild or proof of every historical compiler input'} if not record['licenseMatchesInstalled']: raise SystemExit('Installed license differs from source archive') args.output.mkdir(parents=True, exist_ok=False) (args.output / 'LICENSE').write_bytes(license_text) (args.output / 'verification.json').write_text(json.dumps(record, indent=2) + '\n') print('Verified 51 toml++ headers and the source license')