forked from quic-go/quic-go
http3: allow io.EOF when parsing a capsule fails on the first byte (#4476)
This commit is contained in:
@@ -21,13 +21,29 @@ func (r *exactReader) Read(b []byte) (int, error) {
|
|||||||
return n, err
|
return n, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type countingByteReader struct {
|
||||||
|
io.ByteReader
|
||||||
|
Read int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *countingByteReader) ReadByte() (byte, error) {
|
||||||
|
b, err := r.ByteReader.ReadByte()
|
||||||
|
if err == nil {
|
||||||
|
r.Read++
|
||||||
|
}
|
||||||
|
return b, err
|
||||||
|
}
|
||||||
|
|
||||||
// ParseCapsule parses the header of a Capsule.
|
// ParseCapsule parses the header of a Capsule.
|
||||||
// It returns an io.LimitedReader that can be used to read the Capsule value.
|
// It returns an io.LimitedReader that can be used to read the Capsule value.
|
||||||
// The Capsule value must be read entirely (i.e. until the io.EOF) before using r again.
|
// The Capsule value must be read entirely (i.e. until the io.EOF) before using r again.
|
||||||
func ParseCapsule(r quicvarint.Reader) (CapsuleType, io.Reader, error) {
|
func ParseCapsule(r quicvarint.Reader) (CapsuleType, io.Reader, error) {
|
||||||
ct, err := quicvarint.Read(r)
|
cbr := countingByteReader{ByteReader: r}
|
||||||
|
ct, err := quicvarint.Read(&cbr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == io.EOF {
|
// If an io.EOF is returned without consuming any bytes, return it unmodified.
|
||||||
|
// Otherwise, return an io.ErrUnexpectedEOF.
|
||||||
|
if err == io.EOF && cbr.Read > 0 {
|
||||||
return 0, nil, io.ErrUnexpectedEOF
|
return 0, nil, io.ErrUnexpectedEOF
|
||||||
}
|
}
|
||||||
return 0, nil, err
|
return 0, nil, err
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ var _ = Describe("Capsule", func() {
|
|||||||
|
|
||||||
It("writes capsules", func() {
|
It("writes capsules", func() {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
WriteCapsule(&buf, 1337, []byte("foobar"))
|
Expect(WriteCapsule(&buf, 1337, []byte("foobar"))).To(Succeed())
|
||||||
|
|
||||||
ct, r, err := ParseCapsule(&buf)
|
ct, r, err := ParseCapsule(&buf)
|
||||||
Expect(err).ToNot(HaveOccurred())
|
Expect(err).ToNot(HaveOccurred())
|
||||||
@@ -44,7 +44,11 @@ var _ = Describe("Capsule", func() {
|
|||||||
for i := range b {
|
for i := range b {
|
||||||
ct, r, err := ParseCapsule(bytes.NewReader(b[:i]))
|
ct, r, err := ParseCapsule(bytes.NewReader(b[:i]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
Expect(err).To(MatchError(io.ErrUnexpectedEOF))
|
if i == 0 {
|
||||||
|
Expect(err).To(MatchError(io.EOF))
|
||||||
|
} else {
|
||||||
|
Expect(err).To(MatchError(io.ErrUnexpectedEOF))
|
||||||
|
}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
Expect(ct).To(BeEquivalentTo(1337))
|
Expect(ct).To(BeEquivalentTo(1337))
|
||||||
|
|||||||
Reference in New Issue
Block a user