github.com/AESNooper/go/src@v0.0.0-20220218095104-b56a4ab1bbbb/internal/fuzz/encoding_test.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package fuzz 6 7 import ( 8 "strconv" 9 "strings" 10 "testing" 11 ) 12 13 func TestUnmarshalMarshal(t *testing.T) { 14 var tests = []struct { 15 in string 16 ok bool 17 }{ 18 { 19 in: "int(1234)", 20 ok: false, // missing version 21 }, 22 { 23 in: `go test fuzz v1 24 string("a"bcad")`, 25 ok: false, // malformed 26 }, 27 { 28 in: `go test fuzz v1 29 int()`, 30 ok: false, // empty value 31 }, 32 { 33 in: `go test fuzz v1 34 uint(-32)`, 35 ok: false, // invalid negative uint 36 }, 37 { 38 in: `go test fuzz v1 39 int8(1234456)`, 40 ok: false, // int8 too large 41 }, 42 { 43 in: `go test fuzz v1 44 int(20*5)`, 45 ok: false, // expression in int value 46 }, 47 { 48 in: `go test fuzz v1 49 int(--5)`, 50 ok: false, // expression in int value 51 }, 52 { 53 in: `go test fuzz v1 54 bool(0)`, 55 ok: false, // malformed bool 56 }, 57 { 58 in: `go test fuzz v1 59 byte('aa)`, 60 ok: false, // malformed byte 61 }, 62 { 63 in: `go test fuzz v1 64 byte('☃')`, 65 ok: false, // byte out of range 66 }, 67 { 68 in: `go test fuzz v1 69 string("has final newline") 70 `, 71 ok: true, // has final newline 72 }, 73 { 74 in: `go test fuzz v1 75 string("extra") 76 []byte("spacing") 77 `, 78 ok: true, // extra spaces in the final newline 79 }, 80 { 81 in: `go test fuzz v1 82 float64(0) 83 float32(0)`, 84 ok: true, // will be an integer literal since there is no decimal 85 }, 86 { 87 in: `go test fuzz v1 88 int(-23) 89 int8(-2) 90 int64(2342425) 91 uint(1) 92 uint16(234) 93 uint32(352342) 94 uint64(123) 95 rune('œ') 96 byte('K') 97 byte('ÿ') 98 []byte("hello¿") 99 []byte("a") 100 bool(true) 101 string("hello\\xbd\\xb2=\\xbc ⌘") 102 float64(-12.5) 103 float32(2.5)`, 104 ok: true, 105 }, 106 } 107 for _, test := range tests { 108 t.Run(test.in, func(t *testing.T) { 109 vals, err := unmarshalCorpusFile([]byte(test.in)) 110 if test.ok && err != nil { 111 t.Fatalf("unmarshal unexpected error: %v", err) 112 } else if !test.ok && err == nil { 113 t.Fatalf("unmarshal unexpected success") 114 } 115 if !test.ok { 116 return // skip the rest of the test 117 } 118 newB := marshalCorpusFile(vals...) 119 if err != nil { 120 t.Fatalf("marshal unexpected error: %v", err) 121 } 122 if newB[len(newB)-1] != '\n' { 123 t.Error("didn't write final newline to corpus file") 124 } 125 before, after := strings.TrimSpace(test.in), strings.TrimSpace(string(newB)) 126 if before != after { 127 t.Errorf("values changed after unmarshal then marshal\nbefore: %q\nafter: %q", before, after) 128 } 129 }) 130 } 131 } 132 133 // BenchmarkMarshalCorpusFile measures the time it takes to serialize byte 134 // slices of various sizes to a corpus file. The slice contains a repeating 135 // sequence of bytes 0-255 to mix escaped and non-escaped characters. 136 func BenchmarkMarshalCorpusFile(b *testing.B) { 137 buf := make([]byte, 1024*1024) 138 for i := 0; i < len(buf); i++ { 139 buf[i] = byte(i) 140 } 141 142 for sz := 1; sz <= len(buf); sz <<= 1 { 143 sz := sz 144 b.Run(strconv.Itoa(sz), func(b *testing.B) { 145 for i := 0; i < b.N; i++ { 146 b.SetBytes(int64(sz)) 147 marshalCorpusFile(buf[:sz]) 148 } 149 }) 150 } 151 } 152 153 // BenchmarkUnmarshalCorpusfile measures the time it takes to deserialize 154 // files encoding byte slices of various sizes. The slice contains a repeating 155 // sequence of bytes 0-255 to mix escaped and non-escaped characters. 156 func BenchmarkUnmarshalCorpusFile(b *testing.B) { 157 buf := make([]byte, 1024*1024) 158 for i := 0; i < len(buf); i++ { 159 buf[i] = byte(i) 160 } 161 162 for sz := 1; sz <= len(buf); sz <<= 1 { 163 sz := sz 164 data := marshalCorpusFile(buf[:sz]) 165 b.Run(strconv.Itoa(sz), func(b *testing.B) { 166 for i := 0; i < b.N; i++ { 167 b.SetBytes(int64(sz)) 168 unmarshalCorpusFile(data) 169 } 170 }) 171 } 172 }