Skip to content

fuzz: sizes_vs_core, core's byte ranges held to the real encoders - #119

Draft
Kinflou wants to merge 2 commits into
mainfrom
fuzz/sizes-vs-core
Draft

Kinflou wants to merge 2 commits into
mainfrom
fuzz/sizes-vs-core

Conversation

@Kinflou

@Kinflou Kinflou commented Nov 11, 2026

Copy link
Copy Markdown
Member

Step 4 of the per-format sizes work: the guarantee that core's ranges are proven against the real encoders, not trusted.

Pins an unmerged core commit. runtime/fuzz depends on comline-core at 20c72f0566faa7dd8ebef54a03b916fcea196655, the head of ComlineProject/core#242 (sizes/per-format). It will be re-pinned at the merge commit once #242 lands. Only the fuzz crate depends on core (default features off: the IR alone); the runtime library never does. The fuzz crate's lockfile isn't tracked.

What it checks

A random bounded type graph is frozen as core's TypeRefs (with a Lookup), sized by core for packed@1, msgpack@1 and json@1, and values of it are encoded by the runtime's real formats through the conformance crate's Wire:

  • every value's length is in [min, max], and encoded_len equals it;
  • core's min and max witnesses are values of the type and encode to exactly min and max (unless upper_bound);
  • core sizes a type exactly when the generator can build a value of it.

The generator (runtime/fuzz/src/sizes.rs): all primitives with u128/i128, char, char[max N], char[N], T[], T[max N], T[N] with bounds at the header tiers and past what a header says, optional fields, unit enums up to 200 variants with long names, nested structs and aliases, and recursion under @max_depth (or none). Values come in three styles: the simplest, random, and at the bounds (full strings of four-byte and JSON-escaped characters, longest counts, widest numbers and variants).

Where

  • sizes_vs_core fuzz target (runtime/fuzz/fuzz_targets/), in the README's targets table, so the PR and nightly fuzz matrix picks it up.
  • runtime/fuzz/tests/sizes.rs: the proptest twin, plus deterministic tests for the tiers a vector can't store (msgpack array of 65536 items, 3- and 4-byte varint lengths up to 2^21 characters, longest f32/f64 JSON forms, 200-variant enum, recursion to its limit). A new sizes job in fuzz.yml runs it on pull requests and nightly.

Kinflou added 2 commits November 11, 2026 09:04
A bounded type graph (primitives with the 128-bit integers, char[max N],
char[N], T[], T[max N], T[N], optional fields, unit enums of up to 200
variants, structs, aliases, recursion under @max_depth) is frozen as
comline-core's TypeRef and sized by it for packed@1, msgpack@1 and json@1.
Values of the type (the simplest, a random one, one at the bounds) are
encoded with the real formats through the conformance crate's Wire: their
length must lie in core's [min, max] and encoded_len must agree, and core's
min and max witnesses must encode to exactly min and max.

tests/sizes.rs is the proptest twin, with the tiers too large for a vector:
a msgpack array of 65536 items, 3- and 4-byte varint lengths, an enum of 200
variants, recursion to its limit, the longest JSON floats.

The fuzz crate pins comline-core at an unmerged commit of
ComlineProject/core#242, to be re-pinned at its merge commit.
An array of char in the IR is a string (char[N], char[max N]): the generator
made tuples of chars, which core rightly sized as strings. And a run spent its
time building large witnesses (a serde_json::Value a node), at 19 execs/s: one
input in sixteen is big (the tiers that need 65536 items or 2^21 characters),
the rest small.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant