Skip to content

Fuzz the .ids and .idp parsers and the schema compiler - #215

Merged
Kinflou merged 1 commit into
masterfrom
test/parser-fuzz
Nov 9, 2026
Merged

Kinflou merged 1 commit into
masterfrom
test/parser-fuzz

Conversation

@Kinflou

@Kinflou Kinflou commented Nov 9, 2026

Copy link
Copy Markdown
Member

Closes the last item on #9: fuzz the .ids and .idp parsers. Any input must not panic, and every refusal must come back as a diagnostic with a span.

Targets (core/fuzz, its own crate, nightly)

Target Runs Checks
ids_parse parse_schema no panic or stack overflow; a refusal gives at least one diagnostic, each with a span in bounds and on character boundaries, secondary spans included
ids_compile parse_schema, then check_and_from_declarations the same for the compiler's checks; compiled units round-trip through the store's CBOR unchanged, with the same schema_ir_hash (core#172 was a schema that built and then couldn't be read back)
idp_parse the config.idp grammar, then interpret_context the same for a config: the diagnostic from_config_source reports has a span, and interpreting never panics
  • Seeds: the repo's own .ids and .idp files, copied by seed-corpus.sh.
  • Dictionaries: each grammar's tokens, in ids.dict and idp.dict.
  • Input size: capped at 1 KiB with -max_len=1024. Under the address sanitizer the tree-sitter parser costs about 1 ms per KiB, and parser bugs show up in short inputs.

CI (.github/workflows/fuzz.yml)

It follows runtime's fuzz workflow:

  • Pull requests: only those touching the compiler; 60 s per target.
  • Nightly: at 03:47 UTC, 10 min per target on every core with -fork=$(nproc), from a cached corpus.
  • Failures: the crash is minimised and uploaded. On the nightly, an issue is opened, deduplicated by title.

Local results

Run on 6 cores:

  • ids_parse and idp_parse: 5 min each.
  • ids_compile: 5 min, then another 3 min with the CBOR round trip.

That's about 100,000 inputs per target, with no findings. The two panics in #175 aren't reachable from these entry points, as that issue already says.

Not included: publishing a core.fuzz.json to the observatory. runtime's fuzz-report.py would first have to become a shared action.

Refs #9

Three cargo-fuzz targets in core/fuzz (its own crate, outside the
workspace): ids_parse, ids_compile and idp_parse. Each checks that any
text never panics, and that a refusal comes back as diagnostics whose
spans point inside the input. ids_compile also sends what it compiles
through the store's CBOR and back, comparing the units and the IR hash.

The Fuzz workflow runs each target for 60 s on a pull request that
touches the compiler, and for 10 min nightly on every core (fork mode)
from a cached corpus, opening an issue on a failure. Seeds are the
repo's own schemas and configs; dictionaries hold each grammar's tokens.

Refs #9
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