Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .github/distribution.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,15 +52,15 @@
"linux": "Archive SHA-256 checksums; no detached publisher signature"
},
"release_features": [
"Convert the embedded data of a JavaScript shell page instead of refusing it: title, description, JSON-LD text and noscript text from the static HTML, when the body text reaches 200 characters. The capture is partial, snapshot kind embedded_data, with one javascript_required error. This reads pages such as an Airbnb listing, a SoundCloud track or a Bluesky profile; crates.io still refuses.",
"Name AWS WAF challenge pages as challenge aws-waf, such as IMDb or Binance pages answered with HTTP 202, instead of refusing them as javascript_required."
"Inspect original source bytes independently of readable conversion for all 15 supported extensions, with a deterministic JSON report and exact retrievable artifacts.",
"Expose discovered links and literal code as inert content, including source findings omitted from the readable projection."
],
"release_fixes": [
"Verify --url TLS with the operating system trust store through truststore 0.10.5, so pages whose root is only in that store, such as GlobalSign Root R46 on macOS, load instead of refusing at tls. The macOS and Windows verifiers may fetch missing intermediates themselves."
"Keep source cell addresses and sparse positions in workbook output, with typed values, formulas and cached results retained in inspection.",
"Retain requested inspection artifacts when readable conversion refuses, while leaving existing Markdown output untouched."
],
"release_pr": 70,
"release_examples": [
"brewdoc --url https://soundcloud.com/forss/flickermood --out track.md"
"brewdoc file.pdf --artifact inspection/report=inspection.json --out file.md"
],
"releases": {
"0.2.0": {
Expand Down
19 changes: 15 additions & 4 deletions .github/workflows/build_npm.py
Original file line number Diff line number Diff line change
Expand Up @@ -373,7 +373,7 @@ def file_inventory(folder: Path, *, target: str | None = None) -> dict:
for path in sorted(folder.rglob("*")) if path.is_file()}


def verify_tarball(path: Path, record: dict) -> None:
def verify_tarball(path: Path, record: dict, *, inspection: dict | None = None) -> None:
"""Check the actual npm archive's complete file list, bytes and modes."""
payload = path.read_bytes()
if (len(payload), digest(payload), integrity(payload)) != (record["bytes"], record["sha256"], record["integrity"]):
Expand All @@ -395,6 +395,8 @@ def verify_tarball(path: Path, record: dict) -> None:
native = json.loads(archive.extractfile("package/native-manifest.json").read())
verified = json.loads(archive.extractfile("package/native-verification.json").read())
helper = native_builder()
helper.verifier().admit_inspection(native, version=record["version"], source_sha=record["source_sha"],
inspection=inspection)
helper.validate_manifest(native)
helper.validate_verification(native, verified)
if len({verification_scope(value) for value in (native, verified, record)}) != 1:
Expand Down Expand Up @@ -677,6 +679,8 @@ def consumer_probe(arguments: list[str], work: Path, environment: dict, native:
if (check.returncode, check.stdout, check.stderr) != (0, ("self-check: ok (38 checks)" + os.linesep).encode("ascii"), b""):
raise ValueError(f"npm consumer self-check changed (exit {check.returncode}; "
f"stdout={check.stdout[:512]!r}; stderr={check.stderr[:512]!r})")
packet = helper.verifier().admit_inspection(native, version=native["version"], source_sha=native["source_sha"])
inspection = {"inspection": helper.probe_inspection_cli(arguments, work, environment, packet)} if packet is not None else {}
if verification_scope(native) == "smoke":
if native["oracle"] != [] or len(native["probes"]) != 2 or {row["probe"] for row in native["probes"]} != {"epub2", "formula"}:
raise ValueError("npm smoke requires exactly the synthetic native probes")
Expand All @@ -689,7 +693,7 @@ def consumer_probe(arguments: list[str], work: Path, environment: dict, native:
copied.write_bytes(payload)
helper.check_output(cli_result(arguments, [str(copied)], work, environment), row)
return {"self_check": 38, "selected_package": selected_package, "fixtures": [],
"probes": [{"probe": "epub2", "path": row["path"], "markdown_sha256": row["markdown_sha256"]}]}
"probes": [{"probe": "epub2", "path": row["path"], "markdown_sha256": row["markdown_sha256"]}], **inspection}
help_result = cli_result(arguments, ["--help"], work, environment, 45)
if help_result.returncode != 0 or help_result.stderr or not help_result.stdout.startswith(b"usage: brewdoc"):
raise ValueError("npm consumer help changed")
Expand All @@ -712,7 +716,7 @@ def consumer_probe(arguments: list[str], work: Path, environment: dict, native:
1, False, 0, b"preserve existing output\n", b""):
raise ValueError("npm consumer changed atomic malformed refusal")
return {"self_check": 38, "selected_package": selected_package, "fixtures": fixtures,
"atomic_refusal": True, "help_sha256": digest(help_result.stdout)}
"atomic_refusal": True, "help_sha256": digest(help_result.stdout), **inspection}


def process_snapshot() -> dict:
Expand Down Expand Up @@ -936,6 +940,7 @@ def probe(input_dir: Path, target: str, mode: str, output: Path, smoke: bool = F
packages["local"] = local_prefix / "node_modules/brewdoc"
packages["npx"] = npx_packages[0]
consumers = {}
helper = native_builder()
for name, folder in packages.items():
installed_identity(folder, manifest["packages"][-1], dependencies=True)
resolution = subprocess.run([node, "-e", "process.stdout.write(require.resolve(process.argv[1],{paths:[process.argv[2]]}))",
Expand All @@ -952,15 +957,21 @@ def probe(input_dir: Path, target: str, mode: str, output: Path, smoke: bool = F
raise ValueError("Installed npm native source identity differs")
if verification_scope(native) != scope:
raise ValueError("Installed npm verification scope differs")
packet = helper.verifier().admit_inspection(native, version=manifest["version"],
source_sha=manifest["source_sha"])
consumer_work = work / ("consumer-" + name)
consumer_work.mkdir()
bin_paths = {"global": global_prefix / ("brewdoc.cmd" if os.name == "nt" else "bin/brewdoc"),
"local": local_prefix / "node_modules/.bin" / ("brewdoc.cmd" if os.name == "nt" else "brewdoc")}
arguments = [str(bin_paths[name])] if name != "npx" else []
if name == "npx":
arguments = npm_command(["--yes", f"--package={package}", "brewdoc"], npx=True)
if smoke and name == "npx":
consumers[name] = {"self_check": 38, "selected_package": selected["metadata"]["name"], "fixtures": [], "probes": []}
if packet is not None:
consumers[name]["inspection"] = helper.probe_inspection_cli(arguments, consumer_work, environment, packet)
else:
consumers[name] = consumer_probe(arguments, work, environment, native, selected["metadata"]["name"])
consumers[name] = consumer_probe(arguments, consumer_work, environment, native, selected["metadata"]["name"])
cancellation = cancellation_probe(packages["global" if smoke else "local"] / "bin/brewdoc.cjs", work, environment,
target != "windows-x64", native_binary=cancellation_binary)
signatures = None
Expand Down
Loading
Loading