diff --git a/pkg/base/body_test.go b/pkg/base/body_test.go index 605ab8d5..8bf6b1f4 100644 --- a/pkg/base/body_test.go +++ b/pkg/base/body_test.go @@ -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) { for _, ca := range casesBody { 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))) + }) +} diff --git a/pkg/base/header.go b/pkg/base/header.go index 4c9aeb76..f138afc0 100644 --- a/pkg/base/header.go +++ b/pkg/base/header.go @@ -49,7 +49,6 @@ func (h *Header) unmarshal(br *bufio.Reader) error { if err != nil { return err } - break } @@ -62,6 +61,7 @@ func (h *Header) unmarshal(br *bufio.Reader) error { if err != nil { return fmt.Errorf("value is missing") } + key += string(byts[:len(byts)-1]) key = headerKeyNormalize(key) diff --git a/pkg/base/header_test.go b/pkg/base/header_test.go index e4d4b56c..b5abc3f2 100644 --- a/pkg/base/header_test.go +++ b/pkg/base/header_test.go @@ -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) { for _, ca := range cases { 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))) + }) +} diff --git a/pkg/base/interleaved_frame.go b/pkg/base/interleaved_frame.go index 263d43a2..88aee8d0 100644 --- a/pkg/base/interleaved_frame.go +++ b/pkg/base/interleaved_frame.go @@ -40,10 +40,7 @@ func (f *InterleavedFrame) Unmarshal(br *bufio.Reader) error { f.Payload = make([]byte, payloadLen) _, err = io.ReadFull(br, f.Payload) - if err != nil { - return err - } - return nil + return err } // MarshalSize returns the size of an InterleavedFrame. diff --git a/pkg/base/interleaved_frame_test.go b/pkg/base/interleaved_frame_test.go index c594e436..289ad2a7 100644 --- a/pkg/base/interleaved_frame_test.go +++ b/pkg/base/interleaved_frame_test.go @@ -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) { for _, ca := range casesInterleavedFrame { 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))) + }) +} diff --git a/pkg/base/request_test.go b/pkg/base/request_test.go index 4496fedb..2b33e600 100644 --- a/pkg/base/request_test.go +++ b/pkg/base/request_test.go @@ -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) { for _, ca := range casesRequest { t.Run(ca.name, func(t *testing.T) { @@ -250,3 +175,17 @@ func TestRequestString(t *testing.T) { require.NoError(t, err) 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))) + }) +} diff --git a/pkg/base/response_test.go b/pkg/base/response_test.go index da6ece50..6d1fed4b 100644 --- a/pkg/base/response_test.go +++ b/pkg/base/response_test.go @@ -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) { for _, c := range casesResponse { t.Run(c.name, func(t *testing.T) { @@ -224,3 +154,17 @@ func TestResponseString(t *testing.T) { require.NoError(t, err) 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))) + }) +} diff --git a/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/4f09e183fc071686 b/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/4f09e183fc071686 new file mode 100644 index 00000000..4e0e2401 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/4f09e183fc071686 @@ -0,0 +1,3 @@ +go test fuzz v1 +string("-1") +[]byte("") diff --git a/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/9ee66b42b76b593e b/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/9ee66b42b76b593e new file mode 100644 index 00000000..4bd7aeb7 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/9ee66b42b76b593e @@ -0,0 +1,3 @@ +go test fuzz v1 +string("A") +[]byte("") diff --git a/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/b7287f24b43f09a1 b/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/b7287f24b43f09a1 new file mode 100644 index 00000000..34038d87 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzBodyUnmarshal/b7287f24b43f09a1 @@ -0,0 +1,3 @@ +go test fuzz v1 +string("1000000") +[]byte("0") diff --git a/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/285d6feb3fc28ccd b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/285d6feb3fc28ccd new file mode 100644 index 00000000..bdf99c64 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/285d6feb3fc28ccd @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0:\r") diff --git a/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/582528ddfad69eb5 b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/582528ddfad69eb5 new file mode 100644 index 00000000..a96f5599 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/582528ddfad69eb5 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0") diff --git a/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/76b313744a0792b9 b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/76b313744a0792b9 new file mode 100644 index 00000000..bb8adb2e --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/76b313744a0792b9 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0:") diff --git a/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/a6b4e306e9268e2d b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/a6b4e306e9268e2d new file mode 100644 index 00000000..fd30219f --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/a6b4e306e9268e2d @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0:0") diff --git a/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/fbf6c57247633990 b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/fbf6c57247633990 new file mode 100644 index 00000000..f26f1e0f --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzHeaderUnmarshal/fbf6c57247633990 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("\r") diff --git a/pkg/base/testdata/fuzz/FuzzInterleavedFrameUnmarshal/06ba4bdb19de593e b/pkg/base/testdata/fuzz/FuzzInterleavedFrameUnmarshal/06ba4bdb19de593e new file mode 100644 index 00000000..7fd7a20e --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzInterleavedFrameUnmarshal/06ba4bdb19de593e @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0000") diff --git a/pkg/base/testdata/fuzz/FuzzInterleavedFrameUnmarshal/582528ddfad69eb5 b/pkg/base/testdata/fuzz/FuzzInterleavedFrameUnmarshal/582528ddfad69eb5 new file mode 100644 index 00000000..a96f5599 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzInterleavedFrameUnmarshal/582528ddfad69eb5 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/25b856b4be54317a b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/25b856b4be54317a new file mode 100644 index 00000000..4407e1b0 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/25b856b4be54317a @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0 rtsp:# RTSP/1.0\r") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/2d3b44ca51415d81 b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/2d3b44ca51415d81 new file mode 100644 index 00000000..f3ac2732 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/2d3b44ca51415d81 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0 ") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/582528ddfad69eb5 b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/582528ddfad69eb5 new file mode 100644 index 00000000..a96f5599 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/582528ddfad69eb5 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/930f49fab2367014 b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/930f49fab2367014 new file mode 100644 index 00000000..7390d063 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/930f49fab2367014 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte(" ") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/af9bedcb9e0a31e8 b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/af9bedcb9e0a31e8 new file mode 100644 index 00000000..778cc615 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/af9bedcb9e0a31e8 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0 ") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/c00bf8bc3fad7b79 b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/c00bf8bc3fad7b79 new file mode 100644 index 00000000..206ed86b --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/c00bf8bc3fad7b79 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0 rtsp: 0\r") diff --git a/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/cbfca665ecc31440 b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/cbfca665ecc31440 new file mode 100644 index 00000000..d1fcd81b --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzRequestUnmarshal/cbfca665ecc31440 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0 rtsp: 0") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/0077fea77f30e335 b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/0077fea77f30e335 new file mode 100644 index 00000000..c8ccc595 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/0077fea77f30e335 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("RTSP/1.0 0 0\r") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/02d6e96cd74ed99a b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/02d6e96cd74ed99a new file mode 100644 index 00000000..2612d43b --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/02d6e96cd74ed99a @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("RTSP/1.0 0 0\r\n") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/582528ddfad69eb5 b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/582528ddfad69eb5 new file mode 100644 index 00000000..a96f5599 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/582528ddfad69eb5 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("0") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/930f49fab2367014 b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/930f49fab2367014 new file mode 100644 index 00000000..7390d063 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/930f49fab2367014 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte(" ") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/9a5fcf1ece91d32a b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/9a5fcf1ece91d32a new file mode 100644 index 00000000..ae06c0e7 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/9a5fcf1ece91d32a @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("RTSP/1.0 ") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/dfad58e3da454c29 b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/dfad58e3da454c29 new file mode 100644 index 00000000..75235de0 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/dfad58e3da454c29 @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("RTSP/1.0 0 ") diff --git a/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/ef5fb0d290720baf b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/ef5fb0d290720baf new file mode 100644 index 00000000..22e27e66 --- /dev/null +++ b/pkg/base/testdata/fuzz/FuzzResponseUnmarshal/ef5fb0d290720baf @@ -0,0 +1,2 @@ +go test fuzz v1 +[]byte("RTSP/1.0 0 \r")