github.com/kamalshkeir/kencoding@v0.0.2-0.20230409043843-44b609a0475a/json/fuzz/fuzz.go (about) 1 //go:build ignore 2 // +build ignore 3 4 // Copyright 2015 go-fuzz project authors. All rights reserved. 5 // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file. 6 7 package fuzz 8 9 import ( 10 "bytes" 11 encodingJSON "encoding/json" 12 "fmt" 13 "reflect" 14 15 "github.com/dvyukov/go-fuzz-corpus/fuzz" 16 "github.com/kamalshkeir/kencoding/json" 17 ) 18 19 func fixS(v interface{}) { 20 if s, ok := v.(*S); ok { 21 if len(s.P) == 0 { 22 s.P = []byte(`""`) 23 } 24 } 25 } 26 27 func Fuzz(data []byte) int { 28 score := 0 29 for _, ctor := range []func() interface{}{ 30 func() interface{} { return nil }, 31 func() interface{} { return new([]interface{}) }, 32 func() interface{} { m := map[string]string{}; return &m }, 33 func() interface{} { m := map[string]interface{}{}; return &m }, 34 func() interface{} { return new(S) }, 35 } { 36 // Note: we modified the test to verify that we behavior like the 37 // standard encoding/json package, whether it's right or wrong. 38 v1 := ctor() 39 v2 := ctor() 40 41 err1 := encodingJSON.Unmarshal(data, v1) 42 err2 := json.Unmarshal(data, v2) 43 44 if err1 != nil { 45 if err2 != nil { 46 // both implementations report an error 47 if reflect.TypeOf(err1) != reflect.TypeOf(err2) { 48 fmt.Printf("input: %s\n", string(data)) 49 fmt.Printf("encoding/json.Unmarshal(%T): %T: %s\n", v1, err1, err1) 50 fmt.Printf("segmentio/encoding/json.Unmarshal(%T): %T: %s\n", v2, err2, err2) 51 panic("error types mismatch") 52 } 53 continue 54 } else { 55 fmt.Printf("input: %s\n", string(data)) 56 fmt.Printf("encoding/json.Unmarshal(%T): %T: %s\n", v1, err1, err1) 57 fmt.Printf("segmentio/encoding/json.Unmarshal(%T): <nil>\n") 58 panic("error values mismatch") 59 } 60 } else { 61 if err2 != nil { 62 fmt.Printf("input: %s\n", string(data)) 63 fmt.Printf("encoding/json.Unmarshal(%T): <nil>\n") 64 fmt.Printf("segmentio/encoding/json.Unmarshal(%T): %T: %s\n", v2, err2, err2) 65 panic("error values mismatch") 66 } else { 67 // both implementations pass 68 } 69 } 70 71 score = 1 72 fixS(v1) 73 fixS(v2) 74 if !fuzz.DeepEqual(v1, v2) { 75 fmt.Printf("input: %s\n", string(data)) 76 fmt.Printf("encoding/json: %#v\n", v1) 77 fmt.Printf("segmentio/encoding: %#v\n", v2) 78 panic("not equal") 79 } 80 81 data1, err := encodingJSON.Marshal(v1) 82 if err != nil { 83 panic(err) 84 } 85 data2, err := json.Marshal(v2) 86 if err != nil { 87 panic(err) 88 } 89 if !bytes.Equal(data1, data2) { 90 fmt.Printf("input: %s\n", string(data)) 91 fmt.Printf("encoding/json: %s\n", string(data1)) 92 fmt.Printf("segmentio/encoding: %s\n", string(data2)) 93 panic("not equal") 94 } 95 } 96 return score 97 } 98 99 type S struct { 100 A int `json:",omitempty"` 101 B string `json:"B1,omitempty"` 102 C float64 103 D bool 104 E uint8 105 F []byte 106 G interface{} 107 H map[string]interface{} 108 I map[string]string 109 J []interface{} 110 K []string 111 L S1 112 M *S1 113 N *int 114 O **int 115 P json.RawMessage 116 Q Marshaller 117 R int `json:"-"` 118 S int `json:",string"` 119 } 120 121 type S1 struct { 122 A int 123 B string 124 } 125 126 type Marshaller struct { 127 v string 128 } 129 130 func (m *Marshaller) MarshalJSON() ([]byte, error) { 131 return json.Marshal(m.v) 132 } 133 134 func (m *Marshaller) UnmarshalJSON(data []byte) error { 135 return json.Unmarshal(data, &m.v) 136 }