MCPcopy Create free account
hub / github.com/buger/jsonparser / TestPropertyFuzzHarnessesNoCrash

Function TestPropertyFuzzHarnessesNoCrash

property_test.go:825–876  ·  view source on GitHub ↗

--------------------------------------------------------------------------- Property: all fuzz harnesses from fuzz.go never panic on arbitrary bytes --------------------------------------------------------------------------- This is the OSS-Fuzz invariant — the harness must accept any byte sequence

(t *testing.T)

Source from the content-addressed store, hash-verified

823// reqproof:proptest FuzzParseString, FuzzEachKey, FuzzDelete, FuzzSet, FuzzObjectEach, FuzzParseFloat, FuzzParseInt, FuzzParseBool, FuzzTokenStart, FuzzGetString, FuzzGetFloat, FuzzGetInt, FuzzGetBoolean, FuzzGetUnsafeString
824// Verifies: SYS-REQ-035 [property]
825func TestPropertyFuzzHarnessesNoCrash(t *testing.T) {
826 r := newRNG(jsonSeed + 14)
827 const iterations = 5000
828 // Each harness is a function that takes []byte and returns int (0/1).
829 // We require: (1) no panic, (2) deterministic return for identical input.
830 harnesses := []struct {
831 name string
832 fn func([]byte) int
833 }{
834 {"FuzzParseString", FuzzParseString},
835 {"FuzzEachKey", FuzzEachKey},
836 {"FuzzDelete", FuzzDelete},
837 {"FuzzSet", FuzzSet},
838 {"FuzzObjectEach", FuzzObjectEach},
839 {"FuzzParseFloat", FuzzParseFloat},
840 {"FuzzParseInt", FuzzParseInt},
841 {"FuzzParseBool", FuzzParseBool},
842 {"FuzzTokenStart", FuzzTokenStart},
843 {"FuzzGetString", FuzzGetString},
844 {"FuzzGetFloat", FuzzGetFloat},
845 {"FuzzGetInt", FuzzGetInt},
846 {"FuzzGetBoolean", FuzzGetBoolean},
847 {"FuzzGetUnsafeString", FuzzGetUnsafeString},
848 }
849 // Mix of valid JSON and arbitrary bytes.
850 inputs := make([][]byte, 0, iterations)
851 for i := 0; i < iterations/2; i++ {
852 inputs = append(inputs, randomJSONBytes(r, 2))
853 }
854 for i := 0; i < iterations/2; i++ {
855 inputs = append(inputs, randomBytes(r, 128))
856 }
857 // Curated edge cases.
858 inputs = append(inputs, nil, []byte{}, []byte("\x00"), []byte("\xff"),
859 []byte("{"), []byte("}"), []byte("["), []byte("]"),
860 []byte(`{"test":`), []byte(`{{{`),
861 bytes.Repeat([]byte{0x80}, 256),
862 )
863
864 for _, h := range harnesses {
865 for i, raw := range inputs {
866 if !recoverNoPanic(func() { _ = h.fn(raw) }) {
867 t.Fatalf("%s panicked on input #%d %q", h.name, i, raw)
868 }
869 a := safeCall(h.fn, raw)
870 b := safeCall(h.fn, raw)
871 if a != b {
872 t.Fatalf("%s non-deterministic on input #%d %q: %d vs %d", h.name, i, raw, a, b)
873 }
874 }
875 }
876}
877
878// safeCall invokes a fuzz harness, recovering from any panic and returning
879// the harness result or -1 on panic.

Callers

nothing calls this directly

Calls 5

newRNGFunction · 0.85
randomJSONBytesFunction · 0.85
randomBytesFunction · 0.85
recoverNoPanicFunction · 0.85
safeCallFunction · 0.85

Tested by

no test coverage detected