Adversarial fuzz worker

qa-fuzz-20260729-0002-shape-probe

Session qa-fuzz-20260729-0002 · Worker shape-probe

confirmed_bug

16/20 cases passed. Two depth-cap cases show quadratic-time latency before recursion-limit rejection (GH #169, confirmed_bug). Two bignum cases show silent lossy-f64 precision loss on out-of-range JSON integers with no diagnostic (GH #170, inconclusive).

Fuzz run descriptionIterationsPassResult
Var-file shapes: recursion depth latency and numeric edge cases from the live campaign 20 16/20 FAIL

Inputs exercised

CaseTemplate / inputOutcome
shape-05deep-depth-8000.yaml: recursive map nesting, depth 8000FLAG; 0.697s before ERR_CONFIG_PARSE (feeds F1/GH #169)
shape-06deep-depth-16000.yaml: recursive map nesting, depth 16000FLAG; 2.653s before ERR_CONFIG_PARSE (feeds F1/GH #169)
shape-13bignum-45digit.json: {"value": 999999999999999999999999999999999999999999}FLAG; silently rendered as lossy f64, no diagnostic (feeds F2/GH #170)
shape-14bignum-45digit-negative.json: second 45-digit out-of-range integer literalFLAG; silently rendered as lossy f64, no diagnostic (feeds F2/GH #170)
shape-01,02,03,04,07,08,09,10,11,12,15,16,17,18,19,20Nested/jagged JSON+YAML at moderate depth, empty values, numeric edges, mixed-type arraysPASS; correct / intentional boundary

Findings

F1-shape-probe-quadratic-recursion-latency (GH #169)

Minimal template / frontmatter
{{ a.a.a.a }}
Input
a: {a: {a: {a: ... (depth N nested maps) }}}
Expected
Recursion-limit rejection should be bounded/near-linear in nesting depth, not quadratic.
Observed
Wall time before ERR_CONFIG_PARSE (recursion limit exceeded): depth 500=0.011s, 1000=0.019s, 2000=0.055s, 4000=0.190s, 8000=0.697s, 16000=2.653s, 50000=~25.6s -- quadratic O(depth^2) scaling. Reproduced 3/3 deterministic.
Requirement / ADR
No requirement or ADR currently covers this behavior.
Requirement / ADR follow-up
Create/update an NFR capping var-file ingestion latency before recursion-limit rejection; this is a genuine performance gap, not intentionally unsupported.
Root cause
crates/sc-compose/src/var_file.rs::parse_var_file_contents serde_yaml fallback path re-walks nested structure quadratically in depth before the recursion-limit check fires.
Recommended fix
Move the recursion-depth check to a single top-down pass, or replace the serde_yaml fallback with an iterative depth-tracked parser so depth-N rejection stays near O(N).

F2-shape-probe-silent-bignum-precision-loss (GH #170)

Minimal template / frontmatter
{{ value }}
Input
{"value": 999999999999999999999999999999999999999999}
Expected
Exact-precision preservation, or an explicit numeric-fidelity diagnostic when a JSON integer literal exceeds u64::MAX.
Observed
Exit 0; value silently rendered as 999999999999999900000000000000000000000000.0 (lossy f64 downgrade of a 45-digit integer), no diagnostic.
Requirement / ADR
No requirement or ADR currently covers this behavior.
Requirement / ADR follow-up
Named decision owner needed (team-lead/comp) to decide reject/warn/arbitrary-precision handling for out-of-u64-range JSON integers; document the choice as an ADR once decided.
Root cause
serde_json falls back to an f64 visit for JSON integers outside u64::MAX range; no magnitude/precision guard exists on the JSON var-file ingestion path (unlike the existing YAML NaN/Infinity guard).
Recommended fix
Add a JSON numeric-fidelity guard mirroring the YAML NaN/Infinity guard; file an ADR recording the chosen behavior.