Repository navigation
Add fuzz tests for LZ4FrameInputStream and LZ4BlockInputStream - #179
Open
Dominik-O22 wants to merge 1 commit into
Open
Dominik-O22 wants to merge 1 commit into
Dominik-O22 wants to merge 1 commit into
Conversation
The fuzz suite covered the block codecs and XXHash but not the stream classes. LZ4InputStreamTest feeds raw input to both streams through a mix of read(), read(byte[]), skip() and available() calls taken from a fixed op prefix, and keeps calling after the stream ends or fails. It fails on anything but IOException, on results outside the InputStream contract, on data after the end, on a failure that isn't sticky, and on allocating more than 32 MiB + 4096 bytes per input byte. There is one target per stream class, decompressor and flag combination, each with its own execution in the fuzz profile. Dictionaries hold the magic numbers, and each target has a small valid seed stream, since the fuzzer can't produce a valid block checksum on its own. Closes yawkat#122 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #122. The fuzz suite covered the block codecs and XXHash but not
LZ4FrameInputStreamorLZ4BlockInputStream, which is where recent bugs turned up.LZ4InputStreamTestfollows the issue's plan. The first 16 input bytes are ops, and the rest is the stream, raw with no round-trip. Each op picksread(),read(byte[]),skip()oravailable()and a size, and the ops repeat until the stream ends or fails, then keep going for 32 more calls. A run fails on:IOExceptionInputStreamcontract, including a negativeavailable()orskip()ThreadMXBeanThere's one target per stream class, decompressor and flag combination:
frame_multi,frame_single, andblock_{safe,fast}_{stop,nostop}[_oversized]. Each has its own execution in thefuzzprofile.A few things beyond the issue's sketch:
src/test-resources/.../LZ4InputStreamTestInputs/. Without them, no fuzzed input ever decoded data in a 2-minute run, because the fuzzer can't produce a valid XXHash32 over the block contents. CI runs the seeds in regression mode, so they also give the streams a deterministic run on every build.I didn't add the deep-recursion regression test the issue mentions, because
LZ4BlockStreamingTest.testManyEmptyBlocksRead/Skipalready cover it. The NPE, the descriptorRuntimeExceptionand the per-frame reallocation the issue expected these targets to flag are all fixed onmain. Fuzzing each target for 2 minutes found nothing.Proof:
mvn verifypasses (4127 tests).mvn test -Dtest=LZ4InputStreamTestpasses all 20 regression cases. Each of the 10 targets ran clean for 120 s withJAZZER_FUZZ=1.Reviewed with review-loop: 2 rounds with Claude Opus. Verdict: approved
Created with Claude Opus 5.5 in Claude Code.