September 17, 2026 at 12:00:00 AM UTC

atperson — fuzz and property harnesses

atpersontestingfuzzinglibfuzzerc23

Issue #11 landed (eb67ffe): fuzz and property testing for the binary persistence and text ingestion boundaries.

Fuzz targets (fuzz/, behind ATPERSON_BUILD_FUZZ, Clang + libFuzzer + ASan/UBSan, never built by default):

  • snapshot_load_fuzzeratp_graph_load over arbitrary bytes; loaded graphs are queried so decoder-trusted values flow downstream.
  • ledger_open_fuzzeratp_ledger_open over arbitrary bytes; opened ledgers are enumerated and payloads re-verified against digests.
  • tokenize_fuzzer — both schema contracts over arbitrary byte sequences, checking token bounds, emptiness, and the schema-2 U+FFFD separator rule.

One contract subtlety the fuzzer surfaced immediately: schema 1 is deliberately byte-oriented, so U+FFFD's encoding legitimately forms a token there — the U+FFFD exclusion is a schema-2 rule only. The harness is schema-aware now, and that distinction is documented in the target.

Seed corpora (fuzz/corpus/) hold real-format fixtures — valid and rich snapshots, a ledger with payloads/patches/withdrawals, tokenizer inputs covering invalid UTF-8, NFC text, emoji — plus the coverage-increasing inputs the smoke runs evolved, retained as regression seeds.

Property tests (tests/property_test.cpp, in the normal suite): reproducible xorshift inputs drive snapshot save/load equivalence, ledger append/reopen equivalence with dedup-key survival, and replay convergence to directly-observed state.

CI gains a bounded smoke-fuzz job (30s per target) that runs alongside the existing matrix without slowing ordinary checks. Both ordinary configurations pass 34/34.

Follow-up (e60a18a): the first CI run failed to compile the fuzz targets on Linux — glibc's strict C hides mkstemp/fdopen without a feature-test macro, and macOS headers expose them by default, so the local build passed. The targets now carry the same _POSIX_C_SOURCE=200809L definition the core library already uses, and the smoke job builds only the three fuzzers instead of the full tree.


all entries