-
Notifications
You must be signed in to change notification settings - Fork 1
/
fuzz_test.go
155 lines (152 loc) · 3.81 KB
/
fuzz_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
package peasocket
import (
"bytes"
"io"
"math"
"testing"
)
// The go generate command below adds the fuzz corpus in the cache to git VCS.
//
//go:generate mv $(go env GOCACHE)/fuzz/github.com/soypat/peasocket/. testdata/fuzz/
func FuzzHeaderPut(f *testing.F) {
testCases := []struct {
payloadLen uint64
maskKey uint32
}{
{maskKey: 0, payloadLen: 20},
{maskKey: 0xa2312434, payloadLen: math.MaxUint16 + 20},
{maskKey: 0, payloadLen: math.MaxUint16 + 20},
{maskKey: 0xa2312434, payloadLen: 20},
}
for _, tc := range testCases {
f.Add(tc.payloadLen, tc.maskKey)
}
f.Fuzz(func(t *testing.T, payloadLen uint64, mask uint32) {
if payloadLen == 0 {
return
}
h := newHeader(FrameBinary, payloadLen, mask, false)
var buf [MaxHeaderSize]byte
n, err := h.Put(buf[:])
if err != nil {
panic(err)
}
hgot, n2, err := DecodeHeader(bytes.NewReader(buf[:n]))
if err != nil {
panic(err)
}
if n2 != n {
panic("lengths not equal over wire")
}
if h != hgot {
panic("encoding not match decoding")
}
})
}
func FuzzMaskedReader(f *testing.F) {
testCases := []struct {
data []byte
maskKey uint32
}{
{data: []byte("asd\x00ASd\xff\xf0"), maskKey: 0xa2312434},
{data: []byte("asd\x00ASd\xff\xf0"), maskKey: 0},
}
for _, tc := range testCases {
f.Add(tc.data, tc.maskKey)
}
f.Fuzz(func(t *testing.T, data []byte, maskKey uint32) {
if len(data) == 0 {
return
}
mr := maskedReader{
R: bytes.NewBuffer(data),
MaskKey: maskKey,
}
expect := append([]byte{}, data...)
expectKey := mask(maskKey, expect)
got1 := make([]byte, len(data)/2+1)
expect1 := expect[:len(got1)]
n, err := mr.Read(got1)
if err != nil || n != len(got1) {
t.Fatal(err, n, len(got1))
}
if !bytes.Equal(expect1, got1) {
t.Errorf("expected %q, got %q", expect1, got1)
}
// Proceed with next mask op
got2 := make([]byte, len(expect)-len(got1))
expect2 := expect[len(got1):]
n, err = mr.Read(got2)
if err != nil || n != len(got2) {
t.Fatal(err, n, len(got2))
}
if !bytes.Equal(expect2, got2) {
t.Errorf("second mask op expected %q, got %q", expect2, got2)
}
if expectKey != mr.MaskKey {
t.Errorf("bad mask key, expect %v, got %v", expectKey, mr.MaskKey)
}
})
}
func FuzzLoopbackMessage(f *testing.F) {
testCases := []struct {
data []byte
maskKey uint32
}{
{data: []byte("asd\x00ASd\xff\xf0"), maskKey: 0xa2312434},
{data: []byte("asd\x00ASd\xff\xf0"), maskKey: 0},
}
for _, tc := range testCases {
f.Add(tc.data, tc.maskKey)
}
f.Fuzz(func(t *testing.T, dataCanon []byte, maskKey uint32) {
if len(dataCanon) == 0 {
return
}
trp := &transport{}
loopBuf := &trp.buf
datacp := append([]byte{}, dataCanon...)
tx := &TxBuffered{
trp: trp,
}
rx := Rx{
trp: trp,
}
written, err := tx.WriteMessage(maskKey, datacp)
if err != nil {
t.Fatal(err)
}
actualWritten := loopBuf.Len()
if written != actualWritten {
t.Error("written bytes not match result of WriteMessage", written, loopBuf.Len())
}
callbackCalled := false
rx.RxCallbacks.OnMessage = func(rx *Rx, r io.Reader) error {
callbackCalled = true
b, err := io.ReadAll(r)
if err != nil {
t.Fatal(err)
}
pl := rx.LastReceivedHeader.PayloadLength
if uint64(len(b)) != pl {
t.Error("expected payload length not match read", len(b), pl)
}
if !bytes.Equal(b, dataCanon) {
dataMasked := append([]byte{}, dataCanon...)
maskWS(maskKey, dataMasked)
t.Errorf("data loopback failed for %v\ngot:\n\t%q\nexpect:\n\t%q\nexpect masked:\n\t%q", rx.LastReceivedHeader.String(), b, dataCanon, dataMasked)
}
return nil
}
n, err := rx.ReadNextFrame()
if err != nil {
t.Error(err)
}
if !callbackCalled {
t.Error("callback not called")
}
if n != written {
t.Error("read bytes not match bytes written over loopback", n, actualWritten)
}
})
}