initial commit
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
#!/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')
|
||||
Reference in New Issue
Block a user