Goal
The Python implementation bounds response bodies (--max-response-bytes, default 10 MiB, read incrementally in schemalock/http.py:25-56). The Rust port reads unbounded via response.into_string() (rust/src/runner.rs:95) — an attacker-influenced target could exhaust CI memory. Close the parity gap.
Scope
- Add
--max-response-bytes (default 10 MiB) to the Rust TestArgs CLI struct (rust/src/main.rs), mirroring the Python flag (schemalock/cli.py:35-40).
- Thread the limit into the Runner and replace the unbounded read with a bounded one (e.g.
ureq's into_reader() + .take(limit)), producing an Outcome::Error with a clear detail when a response exceeds the cap — matching Python's ResponseTooLarge.
- Keep the parity gate green: the JSON report shape must not change for responses under the cap.
Why
The repo's core claim is "provably behaviorally equivalent" Python and Rust ports (enforced by scripts/parity_check.py). Today the Rust port lacks a security-relevant Python feature, so the equivalence claim does not hold for --max-response-bytes.
Success criteria
schemalock test --max-response-bytes 100 (Rust binary) errors cleanly against a mock server returning >100 bytes, exit code 1, and reports the cap in the check detail.
- Python and Rust behave identically at several byte boundaries (below/above cap) against the shared mock server.
cargo test --locked, cargo fmt --check, cargo clippy --all-targets -D warnings, and the parity job all pass.
Goal
The Python implementation bounds response bodies (
--max-response-bytes, default 10 MiB, read incrementally in schemalock/http.py:25-56). The Rust port reads unbounded viaresponse.into_string()(rust/src/runner.rs:95) — an attacker-influenced target could exhaust CI memory. Close the parity gap.Scope
--max-response-bytes(default 10 MiB) to the RustTestArgsCLI struct (rust/src/main.rs), mirroring the Python flag (schemalock/cli.py:35-40).ureq'sinto_reader()+.take(limit)), producing anOutcome::Errorwith a clear detail when a response exceeds the cap — matching Python'sResponseTooLarge.Why
The repo's core claim is "provably behaviorally equivalent" Python and Rust ports (enforced by scripts/parity_check.py). Today the Rust port lacks a security-relevant Python feature, so the equivalence claim does not hold for
--max-response-bytes.Success criteria
schemalock test --max-response-bytes 100(Rust binary) errors cleanly against a mock server returning >100 bytes, exit code 1, and reports the cap in the check detail.cargo test --locked,cargo fmt --check,cargo clippy --all-targets -D warnings, and the parity job all pass.