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  }