mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
http3: enforce that DATA frames don't exceed Content-Length (#3980)
This commit is contained in:
parent
56cd866840
commit
5a22ac8970
4 changed files with 124 additions and 6 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/quic-go/quic-go"
|
||||
mockquic "github.com/quic-go/quic-go/internal/mocks/quic"
|
||||
|
||||
"github.com/golang/mock/gomock"
|
||||
|
@ -11,6 +12,11 @@ import (
|
|||
. "github.com/onsi/gomega"
|
||||
)
|
||||
|
||||
func getDataFrame(data []byte) []byte {
|
||||
b := (&dataFrame{Length: uint64(len(data))}).Append(nil)
|
||||
return append(b, data...)
|
||||
}
|
||||
|
||||
var _ = Describe("Stream", func() {
|
||||
Context("reading", func() {
|
||||
var (
|
||||
|
@ -21,10 +27,6 @@ var _ = Describe("Stream", func() {
|
|||
)
|
||||
|
||||
errorCb := func() { errorCbCalled = true }
|
||||
getDataFrame := func(data []byte) []byte {
|
||||
b := (&dataFrame{Length: uint64(len(data))}).Append(nil)
|
||||
return append(b, data...)
|
||||
}
|
||||
|
||||
BeforeEach(func() {
|
||||
buf = &bytes.Buffer{}
|
||||
|
@ -148,3 +150,54 @@ var _ = Describe("Stream", func() {
|
|||
})
|
||||
})
|
||||
})
|
||||
|
||||
var _ = Describe("length-limited streams", func() {
|
||||
var (
|
||||
str *stream
|
||||
qstr *mockquic.MockStream
|
||||
buf *bytes.Buffer
|
||||
)
|
||||
|
||||
BeforeEach(func() {
|
||||
buf = &bytes.Buffer{}
|
||||
qstr = mockquic.NewMockStream(mockCtrl)
|
||||
qstr.EXPECT().Write(gomock.Any()).DoAndReturn(buf.Write).AnyTimes()
|
||||
qstr.EXPECT().Read(gomock.Any()).DoAndReturn(buf.Read).AnyTimes()
|
||||
str = newStream(qstr, func() { Fail("didn't expect error callback to be called") })
|
||||
})
|
||||
|
||||
It("reads all frames", func() {
|
||||
s := newLengthLimitedStream(str, 6)
|
||||
buf.Write(getDataFrame([]byte("foo")))
|
||||
buf.Write(getDataFrame([]byte("bar")))
|
||||
data, err := io.ReadAll(s)
|
||||
Expect(err).ToNot(HaveOccurred())
|
||||
Expect(data).To(Equal([]byte("foobar")))
|
||||
})
|
||||
|
||||
It("errors if more data than the maximum length is sent, in the middle of a frame", func() {
|
||||
s := newLengthLimitedStream(str, 4)
|
||||
buf.Write(getDataFrame([]byte("foo")))
|
||||
buf.Write(getDataFrame([]byte("bar")))
|
||||
qstr.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeMessageError))
|
||||
qstr.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeMessageError))
|
||||
data, err := io.ReadAll(s)
|
||||
Expect(err).To(MatchError(errTooMuchData))
|
||||
Expect(data).To(Equal([]byte("foob")))
|
||||
// check that repeated calls to Read also return the right error
|
||||
n, err := s.Read([]byte{0})
|
||||
Expect(n).To(BeZero())
|
||||
Expect(err).To(MatchError(errTooMuchData))
|
||||
})
|
||||
|
||||
It("errors if more data than the maximum length is sent, as an additional frame", func() {
|
||||
s := newLengthLimitedStream(str, 3)
|
||||
buf.Write(getDataFrame([]byte("foo")))
|
||||
buf.Write(getDataFrame([]byte("bar")))
|
||||
qstr.EXPECT().CancelRead(quic.StreamErrorCode(ErrCodeMessageError))
|
||||
qstr.EXPECT().CancelWrite(quic.StreamErrorCode(ErrCodeMessageError))
|
||||
data, err := io.ReadAll(s)
|
||||
Expect(err).To(MatchError(errTooMuchData))
|
||||
Expect(data).To(Equal([]byte("foo")))
|
||||
})
|
||||
})
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue