mirror of
https://github.com/aler9/gortsplib
synced 2025-10-22 06:39:28 +08:00
base: improve negative tests
This commit is contained in:
@@ -36,6 +36,7 @@ type Header map[string]HeaderValue
|
||||
|
||||
func (h *Header) read(rb *bufio.Reader) error {
|
||||
*h = make(Header)
|
||||
count := 0
|
||||
|
||||
for {
|
||||
byt, err := rb.ReadByte()
|
||||
@@ -52,15 +53,14 @@ func (h *Header) read(rb *bufio.Reader) error {
|
||||
break
|
||||
}
|
||||
|
||||
if len(*h) >= headerMaxEntryCount {
|
||||
return fmt.Errorf("headers count exceeds %d (it's %d)",
|
||||
headerMaxEntryCount, len(*h))
|
||||
if count >= headerMaxEntryCount {
|
||||
return fmt.Errorf("headers count exceeds %d", headerMaxEntryCount)
|
||||
}
|
||||
|
||||
key := string([]byte{byt})
|
||||
byts, err := readBytesLimited(rb, ':', headerMaxKeyLength-1)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("value is missing")
|
||||
}
|
||||
key += string(byts[:len(byts)-1])
|
||||
key = headerKeyNormalize(key)
|
||||
@@ -85,16 +85,13 @@ func (h *Header) read(rb *bufio.Reader) error {
|
||||
}
|
||||
val := string(byts[:len(byts)-1])
|
||||
|
||||
if len(val) == 0 {
|
||||
return fmt.Errorf("empty header value")
|
||||
}
|
||||
|
||||
err = readByteEqual(rb, '\n')
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
(*h)[key] = append((*h)[key], val)
|
||||
count++
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@@ -42,6 +42,16 @@ var casesHeader = []struct {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"empty",
|
||||
[]byte("Testing:\r\n" +
|
||||
"\r\n"),
|
||||
[]byte("Testing: \r\n" +
|
||||
"\r\n"),
|
||||
Header{
|
||||
"Testing": HeaderValue{""},
|
||||
},
|
||||
},
|
||||
{
|
||||
"without space",
|
||||
[]byte("CSeq:2\r\n" +
|
||||
@@ -116,3 +126,50 @@ func TestHeaderWrite(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestHeaderReadErrors(t *testing.T) {
|
||||
for _, ca := range []struct {
|
||||
name string
|
||||
dec []byte
|
||||
err string
|
||||
}{
|
||||
{
|
||||
"empty",
|
||||
[]byte{},
|
||||
"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.read(bufio.NewReader(bytes.NewBuffer(ca.dec)))
|
||||
require.Equal(t, ca.err, err.Error())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@@ -71,7 +71,7 @@ func (req *Request) Read(rb *bufio.Reader) error {
|
||||
|
||||
ur, err := ParseURL(rawURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("unable to parse url (%v)", rawURL)
|
||||
return fmt.Errorf("invalid URL (%v)", rawURL)
|
||||
}
|
||||
req.URL = ur
|
||||
|
||||
|
@@ -160,48 +160,73 @@ func TestRequestReadErrors(t *testing.T) {
|
||||
for _, ca := range []struct {
|
||||
name string
|
||||
byts []byte
|
||||
err string
|
||||
}{
|
||||
{
|
||||
"empty",
|
||||
[]byte{},
|
||||
"EOF",
|
||||
},
|
||||
{
|
||||
"missing url, protocol, eol",
|
||||
[]byte("GET"),
|
||||
"EOF",
|
||||
},
|
||||
{
|
||||
"missing protocol, eol",
|
||||
[]byte("GET rtsp://testing123/test"),
|
||||
"EOF",
|
||||
},
|
||||
{
|
||||
"missing eol",
|
||||
[]byte("GET rtsp://testing123/test RTSP/1.0"),
|
||||
"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 http://testing123 \r\n"),
|
||||
[]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 'RTSP/2.0'",
|
||||
},
|
||||
} {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
var req Request
|
||||
err := req.Read(bufio.NewReader(bytes.NewBuffer(ca.byts)))
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ca.err, err.Error())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRequestReadIgnoreFrames(t *testing.T) {
|
||||
byts := []byte{0x24, 0x6, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4}
|
||||
byts = append(byts, []byte("OPTIONS rtsp://example.com/media.mp4 RTSP/1.0\r\n"+
|
||||
"CSeq: 1\r\n"+
|
||||
"Proxy-Require: gzipped-messages\r\n"+
|
||||
"Require: implicit-play\r\n"+
|
||||
"\r\n")...)
|
||||
|
||||
rb := bufio.NewReader(bytes.NewBuffer(byts))
|
||||
buf := make([]byte, 10)
|
||||
var req Request
|
||||
err := req.ReadIgnoreFrames(rb, buf)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
@@ -164,7 +164,7 @@ func (res *Response) Read(rb *bufio.Reader) error {
|
||||
res.StatusMessage = string(byts[:len(byts)-1])
|
||||
|
||||
if len(res.StatusMessage) == 0 {
|
||||
return fmt.Errorf("empty status")
|
||||
return fmt.Errorf("empty status message")
|
||||
}
|
||||
|
||||
err = readByteEqual(rb, '\n')
|
||||
|
@@ -122,44 +122,58 @@ func TestResponseReadErrors(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 'RTSP/2.0'",
|
||||
},
|
||||
{
|
||||
"code too long",
|
||||
[]byte("RTSP/1.0 1234 OK\r\n"),
|
||||
"buffer length exceeds 4",
|
||||
},
|
||||
{
|
||||
"invalid code",
|
||||
[]byte("RTSP/2.0 string OK\r\n"),
|
||||
[]byte("RTSP/1.0 str OK\r\n"),
|
||||
"unable to parse status code",
|
||||
},
|
||||
{
|
||||
"empty message",
|
||||
[]byte("RTSP/2.0 string \r\n"),
|
||||
[]byte("RTSP/1.0 200 \r\n"),
|
||||
"empty status message",
|
||||
},
|
||||
} {
|
||||
t.Run(ca.name, func(t *testing.T) {
|
||||
var res Response
|
||||
err := res.Read(bufio.NewReader(bytes.NewBuffer(ca.byts)))
|
||||
require.Error(t, err)
|
||||
require.Equal(t, ca.err, err.Error())
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -193,7 +207,7 @@ func TestResponseWriteAutoFillStatus(t *testing.T) {
|
||||
require.Equal(t, byts, buf.Bytes())
|
||||
}
|
||||
|
||||
func TestReadIgnoreFrames(t *testing.T) {
|
||||
func TestResponseReadIgnoreFrames(t *testing.T) {
|
||||
byts := []byte{0x24, 0x6, 0x0, 0x4, 0x1, 0x2, 0x3, 0x4}
|
||||
byts = append(byts, []byte("RTSP/1.0 200 OK\r\n"+
|
||||
"CSeq: 1\r\n"+
|
||||
|
Reference in New Issue
Block a user