============================================================================= The fuzzer (testing.F, native go-fuzz) ============================================================================= FuzzEncodingJSON is the structure-aware differential fuzzer for encoding/json. It reuses the generator (g
(f *testing.F)
| 651 | // Verifies: SYS-REQ-035 [no-panic on malformed input] against the reference |
| 652 | // Go stdlib implementation. |
| 653 | func FuzzEncodingJSON(f *testing.F) { |
| 654 | // Seed with the encoding/json-specific dangerous corpus. |
| 655 | for _, s := range encodingJSONSeeds { |
| 656 | f.Add(s) |
| 657 | } |
| 658 | // Reuse the jsonparser seed corpus (data only) — these are the |
| 659 | // known-dangerous shapes from the structure-aware fuzzer. |
| 660 | for _, s := range structureAwareSeeds { |
| 661 | f.Add(s.data) |
| 662 | } |
| 663 | |
| 664 | f.Fuzz(func(t *testing.T, data []byte) { |
| 665 | // Derive deterministic RNG from the fuzz inputs so generation and |
| 666 | // mutation decisions are a pure function of the engine-supplied |
| 667 | // bytes (coverage feedback stays meaningful). |
| 668 | r := newRandFromSeed(data) |
| 669 | |
| 670 | // --- Structure-aware generation layer (reuse from json_fuzz_test.go) --- |
| 671 | // When the engine mutates data into non-JSON garbage, or ~30% of the |
| 672 | // time regardless, regenerate valid JSON from the grammar. |
| 673 | work := data |
| 674 | if !looksLikeJSON(data) || r.Intn(10) < 3 { |
| 675 | depth := r.Intn(4) // mostly depth 0–3 |
| 676 | if r.Intn(10) == 0 { |
| 677 | depth = 5 + r.Intn(3) // occasionally deep |
| 678 | } |
| 679 | work = genJSON(r, depth) |
| 680 | } |
| 681 | |
| 682 | // --- Deep-nesting injection (Gate D coverage during fuzzing) --- |
| 683 | // Occasionally replace the input with deeply-nested arrays to keep |
| 684 | // stack-safety coverage active during the fuzz campaign. The |
| 685 | // deterministic-depth regression is in TestEncodingJSONCorpusSanity. |
| 686 | if r.Intn(40) == 0 { |
| 687 | depth := 100 * (1 << r.Intn(5)) // 100..1600 |
| 688 | if r.Intn(8) == 0 { |
| 689 | depth = 10000 + r.Intn(90000) // occasionally very deep |
| 690 | } |
| 691 | work = genDeepNesting(depth, r.Intn(2) == 0) |
| 692 | } |
| 693 | |
| 694 | // --- JSON-aware mutation layer (reuse from json_fuzz_test.go) --- |
| 695 | // Apply 0–3 mutations at structural boundaries. |
| 696 | for n := r.Intn(4); n > 0; n-- { |
| 697 | work = applyMutation(r, work) |
| 698 | } |
| 699 | |
| 700 | // --- Gates A–G --- |
| 701 | runEncodingJSONGates(t, work) |
| 702 | }) |
| 703 | } |
| 704 | |
| 705 | // ============================================================================= |
| 706 | // Non-fuzz regression test (runs under plain `go test`) |
nothing calls this directly
no test coverage detected