add fuzz tests (#234)

This commit is contained in:
Alessandro Ros
2023-04-09 18:02:36 +02:00
committed by GitHub
parent 5859c9cb29
commit b6727c07ef
31 changed files with 112 additions and 277 deletions

View File

@@ -33,46 +33,6 @@ func TestBodyUnmarshal(t *testing.T) {
} }
} }
func TestBodyUnmarshalErrors(t *testing.T) {
for _, ca := range []struct {
name string
h Header
byts []byte
err string
}{
{
"invalid body",
Header{
"Content-Length": HeaderValue{"17"},
},
[]byte("123"),
"unexpected EOF",
},
{
"invalid content-length",
Header{
"Content-Length": HeaderValue{"aaa"},
},
[]byte("123"),
"invalid Content-Length",
},
{
"too big content-length",
Header{
"Content-Length": HeaderValue{"1000000"},
},
[]byte("123"),
"Content-Length exceeds 131072 (it's 1000000)",
},
} {
t.Run(ca.name, func(t *testing.T) {
var p body
err := p.unmarshal(ca.h, bufio.NewReader(bytes.NewReader(ca.byts)))
require.EqualError(t, err, ca.err)
})
}
}
func TestBodyMarshal(t *testing.T) { func TestBodyMarshal(t *testing.T) {
for _, ca := range casesBody { for _, ca := range casesBody {
t.Run(ca.name, func(t *testing.T) { t.Run(ca.name, func(t *testing.T) {
@@ -81,3 +41,14 @@ func TestBodyMarshal(t *testing.T) {
}) })
} }
} }
func FuzzBodyUnmarshal(f *testing.F) {
f.Fuzz(func(t *testing.T, a string, b []byte) {
var p body
p.unmarshal(
Header{
"Content-Length": HeaderValue{a},
},
bufio.NewReader(bytes.NewReader(b)))
})
}

View File

@@ -49,7 +49,6 @@ func (h *Header) unmarshal(br *bufio.Reader) error {
if err != nil { if err != nil {
return err return err
} }
break break
} }
@@ -62,6 +61,7 @@ func (h *Header) unmarshal(br *bufio.Reader) error {
if err != nil { if err != nil {
return fmt.Errorf("value is missing") return fmt.Errorf("value is missing")
} }
key += string(byts[:len(byts)-1]) key += string(byts[:len(byts)-1])
key = headerKeyNormalize(key) key = headerKeyNormalize(key)

View File

@@ -116,63 +116,6 @@ func TestHeaderUnmarshal(t *testing.T) {
} }
} }
func TestHeaderUnmarshalErrors(t *testing.T) {
for _, ca := range []struct {
name string
dec []byte
err string
}{
{
"empty",
[]byte{},
"EOF",
},
{
"missing value",
[]byte("Testing:"),
"EOF",
},
{
"missing eol",
[]byte("Testing: val"),
"EOF",
},
{
"r without n",
[]byte("Testing: val\rTesting: val\r\n"),
"expected '\n', got 'T'",
},
{
"final r without n",
[]byte("Testing: val\r\nTesting: val\r\n\r"),
"EOF",
},
{
"missing value",
[]byte("Testing\r\n"),
"value is missing",
},
{
"too many entries",
func() []byte {
var ret []byte
for i := 0; i < headerMaxEntryCount+2; i++ {
ret = append(ret, []byte("Testing: val\r\n")...)
}
ret = append(ret, []byte("\r\n")...)
return ret
}(),
"headers count exceeds 255",
},
} {
t.Run(ca.name, func(t *testing.T) {
h := make(Header)
err := h.unmarshal(bufio.NewReader(bytes.NewBuffer(ca.dec)))
require.EqualError(t, err, ca.err)
})
}
}
func TestHeaderWrite(t *testing.T) { func TestHeaderWrite(t *testing.T) {
for _, ca := range cases { for _, ca := range cases {
t.Run(ca.name, func(t *testing.T) { t.Run(ca.name, func(t *testing.T) {
@@ -181,3 +124,16 @@ func TestHeaderWrite(t *testing.T) {
}) })
} }
} }
func FuzzHeaderUnmarshal(f *testing.F) {
str := ""
for i := 0; i < 300; i++ {
str += "Key: val\r\n"
}
f.Add([]byte(str))
f.Fuzz(func(t *testing.T, b []byte) {
var h Header
h.unmarshal(bufio.NewReader(bytes.NewBuffer(b)))
})
}

View File

@@ -40,10 +40,7 @@ func (f *InterleavedFrame) Unmarshal(br *bufio.Reader) error {
f.Payload = make([]byte, payloadLen) f.Payload = make([]byte, payloadLen)
_, err = io.ReadFull(br, f.Payload) _, err = io.ReadFull(br, f.Payload)
if err != nil {
return err return err
}
return nil
} }
// MarshalSize returns the size of an InterleavedFrame. // MarshalSize returns the size of an InterleavedFrame.

View File

@@ -44,36 +44,6 @@ func TestInterleavedFrameUnmarshal(t *testing.T) {
} }
} }
func TestInterleavedFrameUnmarshalErrors(t *testing.T) {
for _, ca := range []struct {
name string
byts []byte
err string
}{
{
"empty",
[]byte{},
"EOF",
},
{
"invalid magic byte",
[]byte{0x55, 0x00, 0x00, 0x00},
"invalid magic byte (0x55)",
},
{
"payload invalid",
[]byte{0x24, 0x00, 0x00, 0x05, 0x01, 0x02},
"unexpected EOF",
},
} {
t.Run(ca.name, func(t *testing.T) {
var f InterleavedFrame
err := f.Unmarshal(bufio.NewReader(bytes.NewBuffer(ca.byts)))
require.EqualError(t, err, ca.err)
})
}
}
func TestInterleavedFrameMarshal(t *testing.T) { func TestInterleavedFrameMarshal(t *testing.T) {
for _, ca := range casesInterleavedFrame { for _, ca := range casesInterleavedFrame {
t.Run(ca.name, func(t *testing.T) { t.Run(ca.name, func(t *testing.T) {
@@ -83,3 +53,10 @@ func TestInterleavedFrameMarshal(t *testing.T) {
}) })
} }
} }
func FuzzInterleavedFrameUnmarshal(f *testing.F) {
f.Fuzz(func(t *testing.T, b []byte) {
var f InterleavedFrame
f.Unmarshal(bufio.NewReader(bytes.NewBuffer(b)))
})
}

View File

@@ -153,81 +153,6 @@ func TestRequestUnmarshal(t *testing.T) {
} }
} }
func TestRequestUnmarshalErrors(t *testing.T) {
for _, ca := range []struct {
name string
byts []byte
err string
}{
{
"empty",
[]byte{},
"EOF",
},
{
"missing url, protocol, r, n",
[]byte("GET"),
"EOF",
},
{
"missing protocol, r, n",
[]byte("GET rtsp://testing123/test"),
"EOF",
},
{
"missing r, n",
[]byte("GET rtsp://testing123/test RTSP/1.0"),
"EOF",
},
{
"missing n",
[]byte("GET rtsp://testing123/test RTSP/1.0\r"),
"EOF",
},
{
"empty method",
[]byte(" rtsp://testing123 RTSP/1.0\r\n"),
"empty method",
},
{
"empty URL",
[]byte("GET RTSP/1.0\r\n"),
"invalid URL ()",
},
{
"empty protocol",
[]byte("GET rtsp://testing123 \r\n"),
"expected 'RTSP/1.0', got []",
},
{
"invalid URL",
[]byte("GET http://testing123 RTSP/1.0\r\n"),
"invalid URL (http://testing123)",
},
{
"invalid protocol",
[]byte("GET rtsp://testing123 RTSP/2.0\r\n"),
"expected 'RTSP/1.0', got [82 84 83 80 47 50 46 48]",
},
{
"invalid header",
[]byte("GET rtsp://testing123 RTSP/1.0\r\nTesting: val\r"),
"EOF",
},
{
"invalid body",
[]byte("GET rtsp://testing123 RTSP/1.0\r\nContent-Length: 17\r\n\r\n123"),
"unexpected EOF",
},
} {
t.Run(ca.name, func(t *testing.T) {
var req Request
err := req.Unmarshal(bufio.NewReader(bytes.NewBuffer(ca.byts)))
require.EqualError(t, err, ca.err)
})
}
}
func TestRequestMarshal(t *testing.T) { func TestRequestMarshal(t *testing.T) {
for _, ca := range casesRequest { for _, ca := range casesRequest {
t.Run(ca.name, func(t *testing.T) { t.Run(ca.name, func(t *testing.T) {
@@ -250,3 +175,17 @@ func TestRequestString(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, string(byts), req.String()) require.Equal(t, string(byts), req.String())
} }
func FuzzRequestUnmarshal(f *testing.F) {
f.Add([]byte("GET rtsp://testing123/test"))
f.Add([]byte("GET rtsp://testing123/test RTSP/1.0\r\n"))
f.Add([]byte("OPTIONS rtsp://example.com/media.mp4 RTSP/1.0\r\n" +
"Content-Length: 100\r\n" +
"\r\n" +
"testing"))
f.Fuzz(func(t *testing.T, b []byte) {
var req Request
req.Unmarshal(bufio.NewReader(bytes.NewBuffer(b)))
})
}

View File

@@ -105,76 +105,6 @@ func TestResponseUnmarshal(t *testing.T) {
} }
} }
func TestResponseUnmarshalErrors(t *testing.T) {
for _, ca := range []struct {
name string
byts []byte
err string
}{
{
"empty",
[]byte{},
"EOF",
},
{
"missing code, message, eol",
[]byte("RTSP/1.0"),
"EOF",
},
{
"missing message, eol",
[]byte("RTSP/1.0 200"),
"EOF",
},
{
"missing eol",
[]byte("RTSP/1.0 200 OK"),
"EOF",
},
{
"missing eol 2",
[]byte("RTSP/1.0 200 OK\r"),
"EOF",
},
{
"invalid protocol",
[]byte("RTSP/2.0 200 OK\r\n"),
"expected 'RTSP/1.0', got [82 84 83 80 47 50 46 48]",
},
{
"code too long",
[]byte("RTSP/1.0 1234 OK\r\n"),
"buffer length exceeds 4",
},
{
"invalid code",
[]byte("RTSP/1.0 str OK\r\n"),
"unable to parse status code",
},
{
"empty message",
[]byte("RTSP/1.0 200 \r\n"),
"empty status message",
},
{
"invalid header",
[]byte("RTSP/1.0 200 OK\r\nTesting: val\r"),
"EOF",
},
{
"invalid body",
[]byte("RTSP/1.0 200 OK\r\nContent-Length: 17\r\n\r\n123"),
"unexpected EOF",
},
} {
t.Run(ca.name, func(t *testing.T) {
var res Response
err := res.Unmarshal(bufio.NewReader(bytes.NewBuffer(ca.byts)))
require.EqualError(t, err, ca.err)
})
}
}
func TestResponseMarshal(t *testing.T) { func TestResponseMarshal(t *testing.T) {
for _, c := range casesResponse { for _, c := range casesResponse {
t.Run(c.name, func(t *testing.T) { t.Run(c.name, func(t *testing.T) {
@@ -224,3 +154,17 @@ func TestResponseString(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, string(byts), res.String()) require.Equal(t, string(byts), res.String())
} }
func FuzzResponseUnmarshal(f *testing.F) {
f.Add([]byte("RTSP/1.0 "))
f.Add([]byte("RTSP/1.0 200 OK\r\n" +
"Content-Length: 100\r\n" +
"\r\n" +
"testing"))
f.Fuzz(func(t *testing.T, b []byte) {
var res Response
res.Unmarshal(bufio.NewReader(bytes.NewBuffer(b)))
})
}

View File

@@ -0,0 +1,3 @@
go test fuzz v1
string("-1")
[]byte("")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
string("A")
[]byte("")

View File

@@ -0,0 +1,3 @@
go test fuzz v1
string("1000000")
[]byte("0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0:\r")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0:")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0:0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("\r")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0000")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0 rtsp:# RTSP/1.0\r")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0 ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte(" ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0 ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0 rtsp: 0\r")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0 rtsp: 0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("RTSP/1.0 0 0\r")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("RTSP/1.0 0 0\r\n")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("0")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte(" ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("RTSP/1.0 ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("RTSP/1.0 0 ")

View File

@@ -0,0 +1,2 @@
go test fuzz v1
[]byte("RTSP/1.0 0 \r")