clone

a self-hosted multitenant nostr relay with sites, file storage, git hosting, and inbox and outbox delivery

feat/ui-updates
tinyrelay / protocol / nostr / fuzz_test.go
fuzz_test.go 1.7K
1package nostr23import (4 "strings"5 "testing"6)78func TestParseFilterRejectsNonObjectsAndNullFields(t *testing.T) {9 for _, raw := range []string{"null", "[]", `{"since":null}`, `{"until":null}`, `{"limit":null}`, `{"search":null}`, `{"ids":[null]}`, `{"authors":[null]}`, `{"kinds":[null]}`, `{"#t":[null]}`} {10 if _, err := ParseFilter([]byte(raw)); err == nil {11 t.Errorf("accepted invalid filter %s", raw)12 }13 }14}1516// FuzzParse exercises the complete event wire boundary with arbitrary input.17// Parse must reject malformed input without panicking.18func FuzzParse(f *testing.F) {19 f.Add([]byte(`{"id":"","pubkey":"","created_at":0,"kind":1,"tags":[],"content":"","sig":""}`))20 f.Add([]byte(`null`))21 f.Add([]byte(`{"id":1,"tags":null}`))22 seed := Event{CreatedAt: 1_700_000_000, Kind: 1, Tags: [][]string{{"t", "seed"}}, Content: "valid seed"}23 if err := Sign(&seed, strings.Repeat("0", 63)+"1"); err != nil {24 f.Fatal(err)25 }26 encoded, err := Canonical(seed)27 if err != nil {28 f.Fatal(err)29 }30 f.Add(encoded)31 f.Fuzz(func(t *testing.T, raw []byte) {32 _, _ = Parse(raw)33 })34}3536// FuzzParseFilter covers both ordinary and #tag filter keys and checks that37// accepted filters remain safe to marshal and parse again.38func FuzzParseFilter(f *testing.F) {39 f.Add([]byte(`{}`))40 f.Add([]byte(`{"#t":["go"],"kinds":[1],"limit":10}`))41 f.Add([]byte(`{"ids":null,"since":-1,"search":""}`))42 f.Fuzz(func(t *testing.T, raw []byte) {43 filter, err := ParseFilter(raw)44 if err != nil {45 return46 }47 encoded, err := filter.MarshalJSON()48 if err != nil {49 t.Fatalf("marshal accepted filter: %v", err)50 }51 if _, err := ParseFilter(encoded); err != nil {52 t.Fatalf("accepted filter did not round trip: %v", err)53 }54 })55}