This directory contains fuzz testing harnesses for the Payload Schema decoder implementations.
Per the Payload Schema specification, decoders MUST NOT crash on any input.
# Python random fuzzing (10 sec)
make fuzz-quick
# Python Hypothesis property-based testing
make fuzz-hypothesis
# Full Python fuzz suite
make fuzz-all
# Go fuzzing (requires Go 1.18+)
make fuzz-go
# C fuzzing with libFuzzer (requires clang)
make fuzz-cFast random input generation targeting the Python interpreter.
# Quick test (10 seconds)
python tools/fuzz_decoder.py examples/env_sensor.yaml --duration 10
# Full test (10 minutes per schema)
python tools/fuzz_decoder.py examples/env_sensor.yaml --duration 600
# Schema parser fuzzing
python tools/fuzz_decoder.py --schema-fuzz --duration 60
# Reproducible (for debugging crashes)
python tools/fuzz_decoder.py examples/env_sensor.yaml --seed 12345Inputs generated:
- Random byte sequences (0-255 bytes)
- Truncated valid payloads
- Extended valid payloads
- Bit-flipped valid payloads
- All zeros / all 0xFF
- Empty payload
Typical rate: ~90,000 inputs/sec
Property-based testing with intelligent input generation and shrinking.
# Run with pytest
PYTHONPATH=tools pytest tests/test_hypothesis.py -v
# Show statistics
PYTHONPATH=tools pytest tests/test_hypothesis.py -v --hypothesis-show-statistics
# Profiles: default, ci, dev, debug
HYPOTHESIS_PROFILE=ci pytest tests/test_hypothesis.py -vProperties tested:
- Decoder safety (never crashes)
- Roundtrip preservation (encode → decode)
- Type boundary values
- Modifier reversibility
- Bitfield extraction correctness
- Schema parser safety
Native Go fuzzing with coverage-guided input generation.
cd fuzz/go
# Run fuzz tests
go test -fuzz=FuzzDecode -fuzztime=60s
go test -fuzz=FuzzDecodeEncode -fuzztime=60s
# Run unit tests
go test -vFuzz functions:
FuzzDecode- Decoder doesn't panic on any inputFuzzDecodeEncode- Roundtrip preservationFuzzSchemaInterpreter- Generic type handling
Coverage-guided fuzzing for generated C codecs.
Build with clang:
# Generate codec header first
python tools/generate-c.py examples/env_sensor.yaml -o include/env_sensor_codec.h
# Build with libFuzzer
clang -g -fsanitize=fuzzer,address -I include fuzz/fuzz_decoder.c -o fuzz_decoder
# Run
mkdir -p corpus
./fuzz_decoder corpus/ -max_len=256 -runs=1000000Build with AFL:
afl-clang-fast -g -I include fuzz/fuzz_decoder.c -o fuzz_decoder_afl
mkdir -p corpus findings
echo -ne '\x09\x29\x82\x0C\xE4\x00' > corpus/seed1
afl-fuzz -i corpus -o findings ./fuzz_decoder_aflThe .github/workflows/fuzz.yml workflow runs:
| Event | Python Random | Hypothesis | Go Fuzz | C Fuzz |
|---|---|---|---|---|
| PR | 10 sec | default profile | - | - |
| Push to main | 10 min/schema | ci profile | 60 sec | 10 min |
| Nightly schedule | 10 min/schema | ci profile | 60 sec | 10 min |
PASS: No crashes detected
Decoder Fuzzing Results
==================================================
Total inputs: 916040
Crashes: 0
PASSED: No crashes detected
FAIL: Crash detected - needs investigation
Crashes: 1
CRASH INPUTS (reproducible with --seed):
1: 0a0b0c...
FAILED: Decoder crashed on malformed input!
- Per commit: 10 seconds of fuzzing
- Per release: 1 hour of fuzzing
- Coverage: All input sources must be tested
- Add test vectors to schema YAML
- Validate:
make validate-schema SCHEMA=path/to/schema.yaml - Fuzz:
python tools/fuzz_decoder.py path/to/schema.yaml --duration 600