Skip to content

Refuse an absurd payload for every structure, not just the newest - #135

Merged
mattlorimor merged 2 commits into
masterfrom
test/hostile-payload-roster
Aug 20, 2026
Merged

Refuse an absurd payload for every structure, not just the newest#135
mattlorimor merged 2 commits into
masterfrom
test/hostile-payload-roster

Conversation

@mattlorimor

Copy link
Copy Markdown
Owner

TestPersistenceHostilePayloads exercised the field-level guards of 18 of the 33 structures. The drift ran the opposite way from the sweeps fixed in #132 and #133: the structures added most recently were the best covered, and fifteen of the oldest had no field-level test at all — HyperLogLog, DDSketch, ThetaSketch, CountMinSketch, QuotientFilter, BinaryFuseFilter, BloomierFilter, CountSketch, SimHashSignature, InvertibleBloomLookupTable, HyperLogLogPlus, and the four older Bloom variants.

Their readers already had the guards. Nothing exercised them, so a guard that had quietly stopped firing would have been found by a user with an edited file rather than here.

What this covers

Eighteen new tests, each poking one field, repairing the CRC, and asserting the message its own guard produces — the message is the landing assertion, which is what keeps a payload from being refused for the wrong reason. That mattered: three of my fragments ("between", "hash function", "at least one") were loose enough to match an unrelated refusal, and I tightened them and re-ran to confirm the tests still landed where intended.

The offsets come from FORMAT.md, which #133 made complete and testable.

A map, not a loop

TestEveryStructureRefusesSomeAbsurdPayload is the completeness check. It can't be one loop the way the persistence sweeps are, because what counts as absurd differs per structure. So it's a map from each structure to the test carrying it, with both halves checked: the roster comes from StructureId, and each named test must exist and carry [TestMethod].

I first wrote that map with a DeclaredElsewhere exemption list claiming fifteen structures were covered in their own test files. That was false — they were covered in this same file all along, and my exemptions would have quietly excused them from the roster. The map is now all 33 entries with no exemptions, generated by parsing the file rather than transcribed.

Verification

  • Removing HyperLogLog's reader guard → its test fails
  • Removing BinaryFuseFilter's fingerprint-width guard → its test fails
  • Widening ThetaSketch's trailing-value tolerance to every value → its test fails
  • Adding a member to StructureId → the completeness check fails by name
  • Stripping [TestMethod] from a test the map vouches for → fails naming the test

My first attempt at the HyperLogLog probe reported SURVIVED, which I chased before trusting it: the surgery had disabled the constructor's power-of-two check rather than the reader's, so the test was never going to notice. Retargeted at the InvalidDataException site, it kills. A probe that lands in the wrong place is indistinguishable from a test that doesn't work, until you look.

Also removes an orphaned doc comment that had drifted off PokeUInt64 and stacked a second <summary> onto PokeByte.

Clean dotnet build -c Release -warnaserror, exit 0 unpiped. 925 tests passing, up 19.

mattlorimor and others added 2 commits August 19, 2026 22:53
TestPersistenceHostilePayloads exercised the field-level guards of 18 of the 33
structures. The drift ran backwards from the sweeps fixed earlier: the
structures added most recently had the most guards tested, and fifteen of the
oldest -- HyperLogLog, DDSketch, ThetaSketch, CountMinSketch, QuotientFilter,
BinaryFuseFilter, BloomierFilter and the rest -- had none at all.

Their readers already had the guards. Nothing exercised them, so a guard that
had stopped firing would have been found by a user with an edited file rather
than here. Eighteen tests now reach them, each asserting the message its own
guard produces, which is what keeps a payload refused for the right reason.

TestEveryStructureRefusesSomeAbsurdPayload is the completeness check. It cannot
be one loop the way the persistence sweeps are, because what counts as absurd
differs per structure, so it is a map from each structure to the test carrying
it -- with both halves checked. The roster is StructureId, and each named test
has to exist and be a test, so an entry pointing at something renamed or
un-attributed fails rather than silently vouching for nothing.

Also removes an orphaned doc comment that had drifted off PokeUInt64 and stacked
a second <summary> onto PokeByte.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JH2NRDbhF5bwAsTAP7znb9
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JH2NRDbhF5bwAsTAP7znb9
@mattlorimor
mattlorimor merged commit 5470f5f into master Aug 20, 2026
7 checks passed
@mattlorimor
mattlorimor deleted the test/hostile-payload-roster branch August 20, 2026 03:01
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