diff --git a/frames/ack_frame_legacy_test.go b/frames/ack_frame_legacy_test.go index b22844ea..eb8ff6bb 100644 --- a/frames/ack_frame_legacy_test.go +++ b/frames/ack_frame_legacy_test.go @@ -135,6 +135,16 @@ var _ = Describe("AckFrame", func() { Expect(err).To(MatchError(errInvalidNackRanges)) }) }) + + It("errors on EOFs", func() { + data := []byte{0x64, 0x8, 0x23, 0x03, 0x72, 0x1, 0x1, 0x0, 0xc0, 0x15, 0x0, 0x0, 0x4, 0x1, 0x8f, 0x0, 0xff, 0x1, 0x8f, 0x0, 0xff} + _, err := ParseAckFrameLegacy(bytes.NewReader(data), 0) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseAckFrameLegacy(bytes.NewReader(data[0:i]), 0) + Expect(err).To(HaveOccurred()) + } + }) }) Context("GetHighestInOrderPacket", func() { diff --git a/frames/ack_frame_test.go b/frames/ack_frame_test.go index e618d492..5025e25d 100644 --- a/frames/ack_frame_test.go +++ b/frames/ack_frame_test.go @@ -253,6 +253,16 @@ var _ = Describe("AckFrame", func() { }) }) }) + + It("errors on EOFs", func() { + data := []byte{0x65, 0x66, 0x9, 0x23, 0x1, 0x7, 0x7, 0x0, 0xff, 0x0, 0x0, 0xf5, 0x8a, 0x2, 0xc8, 0xe6, 0x0, 0xff, 0x0, 0x0, 0xff, 0x0, 0x0, 0xff, 0x0, 0x0, 0x23, 0x13, 0x0, 0x2, 0x1, 0x13, 0xae, 0xb, 0x0, 0x0, 0x80, 0x5} + _, err := ParseAckFrame(bytes.NewReader(data), 0) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseAckFrame(bytes.NewReader(data[0:i]), 0) + Expect(err).To(MatchError("EOF")) + } + }) }) Context("when writing", func() { diff --git a/frames/blocked_frame_test.go b/frames/blocked_frame_test.go index c497cd0c..9a8aa04f 100644 --- a/frames/blocked_frame_test.go +++ b/frames/blocked_frame_test.go @@ -16,6 +16,16 @@ var _ = Describe("BlockedFrame", func() { Expect(err).ToNot(HaveOccurred()) Expect(frame.StreamID).To(Equal(protocol.StreamID(0xDEADBEEF))) }) + + It("errors on EOFs", func() { + data := []byte{0x05, 0xEF, 0xBE, 0xAD, 0xDE} + _, err := ParseBlockedFrame(bytes.NewReader(data)) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseBlockedFrame(bytes.NewReader(data[0:i])) + Expect(err).To(HaveOccurred()) + } + }) }) Context("when writing", func() { diff --git a/frames/connection_close_frame_test.go b/frames/connection_close_frame_test.go index f65627ea..f7328133 100644 --- a/frames/connection_close_frame_test.go +++ b/frames/connection_close_frame_test.go @@ -35,6 +35,16 @@ var _ = Describe("ConnectionCloseFrame", func() { _, err := ParseConnectionCloseFrame(b) Expect(err).To(MatchError(qerr.Error(qerr.InvalidConnectionCloseData, "reason phrase too long"))) }) + + It("errors on EOFs", func() { + data := []byte{0x40, 0x19, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x4e, 0x6f, 0x20, 0x72, 0x65, 0x63, 0x65, 0x6e, 0x74, 0x20, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x20, 0x61, 0x63, 0x74, 0x69, 0x76, 0x69, 0x74, 0x79, 0x2e} + _, err := ParseConnectionCloseFrame(bytes.NewReader(data)) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseConnectionCloseFrame(bytes.NewReader(data[0:i])) + Expect(err).To(HaveOccurred()) + } + }) }) Context("when writing", func() { diff --git a/frames/goaway_frame_test.go b/frames/goaway_frame_test.go index 30c0416d..bef740a6 100644 --- a/frames/goaway_frame_test.go +++ b/frames/goaway_frame_test.go @@ -40,6 +40,21 @@ var _ = Describe("GoawayFrame", func() { _, err := ParseGoawayFrame(b) Expect(err).To(MatchError(qerr.Error(qerr.InvalidGoawayData, "reason phrase too long"))) }) + + It("errors on EOFs", func() { + data := []byte{0x03, + 0x01, 0x00, 0x00, 0x00, + 0x02, 0x00, 0x00, 0x00, + 0x03, 0x00, + 'f', 'o', 'o', + } + _, err := ParseGoawayFrame(bytes.NewReader(data)) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseGoawayFrame(bytes.NewReader(data[0:i])) + Expect(err).To(HaveOccurred()) + } + }) }) Context("when writing", func() { diff --git a/frames/ping_frame_test.go b/frames/ping_frame_test.go index 7a0ac44e..3637a3bc 100644 --- a/frames/ping_frame_test.go +++ b/frames/ping_frame_test.go @@ -16,6 +16,11 @@ var _ = Describe("PingFrame", func() { Expect(err).ToNot(HaveOccurred()) Expect(b.Len()).To(Equal(0)) }) + + It("errors on EOFs", func() { + _, err := ParsePingFrame(bytes.NewReader(nil)) + Expect(err).To(HaveOccurred()) + }) }) Context("when writing", func() { diff --git a/frames/rst_stream_frame_test.go b/frames/rst_stream_frame_test.go index 4bf3354a..1689938b 100644 --- a/frames/rst_stream_frame_test.go +++ b/frames/rst_stream_frame_test.go @@ -18,6 +18,16 @@ var _ = Describe("RstStreamFrame", func() { Expect(frame.ByteOffset).To(Equal(protocol.ByteCount(0xDECAFBAD11223344))) Expect(frame.ErrorCode).To(Equal(uint32(0x13371234))) }) + + It("errors on EOFs", func() { + data := []byte{0x01, 0xEF, 0xBE, 0xAD, 0xDE, 0x44, 0x33, 0x22, 0x11, 0xAD, 0xFB, 0xCA, 0xDE, 0x34, 0x12, 0x37, 0x13} + _, err := ParseRstStreamFrame(bytes.NewReader(data)) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseRstStreamFrame(bytes.NewReader(data[0:i])) + Expect(err).To(HaveOccurred()) + } + }) }) Context("when writing", func() { diff --git a/frames/stop_waiting_frame_test.go b/frames/stop_waiting_frame_test.go index 2b7c49b1..904eb9f6 100644 --- a/frames/stop_waiting_frame_test.go +++ b/frames/stop_waiting_frame_test.go @@ -9,185 +9,193 @@ import ( ) var _ = Describe("StopWaitingFrame", func() { - Context("stop waiting frames", func() { - Context("when parsing", func() { - It("accepts sample frame", func() { - b := bytes.NewReader([]byte{0x06, 0xA4, 0x03}) - frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.Entropy).To(Equal(byte(0xA4))) - Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2))) - }) + Context("when parsing", func() { + It("accepts sample frame", func() { + b := bytes.NewReader([]byte{0x06, 0xA4, 0x03}) + frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version33) + Expect(err).ToNot(HaveOccurred()) + Expect(frame.Entropy).To(Equal(byte(0xA4))) + Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2))) + }) - It("rejects frames with an invalid LeastUnackedDelta", func() { - b := bytes.NewReader([]byte{0x06, 0xA4, 0xD}) - _, err := ParseStopWaitingFrame(b, 10, 1, protocol.Version33) + It("rejects frames with an invalid LeastUnackedDelta", func() { + b := bytes.NewReader([]byte{0x06, 0xA4, 0xD}) + _, err := ParseStopWaitingFrame(b, 10, 1, protocol.Version33) + Expect(err).To(HaveOccurred()) + }) + + It("reads a StopWaitingFrame, for QUIC version 34", func() { + b := bytes.NewReader([]byte{0x06, 0x03}) + frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version34) + Expect(err).ToNot(HaveOccurred()) + Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2))) + }) + + It("errors on EOFs", func() { + data := []byte{0x06, 0xA4, 0x03} + _, err := ParseStopWaitingFrame(bytes.NewReader(data), 5, 1, protocol.Version33) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseStopWaitingFrame(bytes.NewReader(data[0:i]), 5, 1, protocol.Version33) Expect(err).To(HaveOccurred()) - }) + } + }) + }) - It("reads a StopWaitingFrame, for QUIC version 34", func() { - b := bytes.NewReader([]byte{0x06, 0x03}) - frame, err := ParseStopWaitingFrame(b, 5, 1, protocol.Version34) - Expect(err).ToNot(HaveOccurred()) - Expect(frame.LeastUnacked).To(Equal(protocol.PacketNumber(2))) - }) + Context("when writing", func() { + It("writes a sample frame", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumber: 13, + Entropy: 0xAD, + PacketNumberLen: protocol.PacketNumberLen6, + } + frame.Write(b, protocol.Version33) + Expect(b.Bytes()[0]).To(Equal(uint8(0x06))) + Expect(b.Bytes()[1]).To(Equal(uint8(frame.Entropy))) + Expect(b.Bytes()[2:8]).To(Equal([]byte{3, 0, 0, 0, 0, 0})) }) - Context("when writing", func() { - It("writes a sample frame", func() { + It("writes a sample frame, for QUIC version 34", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumber: 13, + PacketNumberLen: protocol.PacketNumberLen6, + } + frame.Write(b, protocol.Version34) + Expect(b.Bytes()[0]).To(Equal(uint8(0x06))) + Expect(b.Bytes()[1:7]).To(Equal([]byte{3, 0, 0, 0, 0, 0})) + }) + + It("errors when PacketNumber was not set", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumberLen: protocol.PacketNumberLen1, + Entropy: 0xAD, + } + err := frame.Write(b, 0) + Expect(err).To(MatchError(errPacketNumberNotSet)) + }) + + It("errors when PacketNumberLen was not set", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumber: 13, + Entropy: 0xAD, + } + err := frame.Write(b, 0) + Expect(err).To(MatchError(errPacketNumberLenNotSet)) + }) + + It("errors when the LeastUnackedDelta would be negative", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumber: 5, + PacketNumberLen: protocol.PacketNumberLen1, + } + err := frame.Write(b, 0) + Expect(err).To(MatchError(errLeastUnackedHigherThanPacketNumber)) + }) + + Context("LeastUnackedDelta length", func() { + It("writes a 1-byte LeastUnackedDelta", func() { b := &bytes.Buffer{} frame := &StopWaitingFrame{ LeastUnacked: 10, PacketNumber: 13, - Entropy: 0xAD, - PacketNumberLen: protocol.PacketNumberLen6, - } - frame.Write(b, protocol.Version33) - Expect(b.Bytes()[0]).To(Equal(uint8(0x06))) - Expect(b.Bytes()[1]).To(Equal(uint8(frame.Entropy))) - Expect(b.Bytes()[2:8]).To(Equal([]byte{3, 0, 0, 0, 0, 0})) - }) - - It("writes a sample frame, for QUIC version 34", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumber: 13, - PacketNumberLen: protocol.PacketNumberLen6, - } - frame.Write(b, protocol.Version34) - Expect(b.Bytes()[0]).To(Equal(uint8(0x06))) - Expect(b.Bytes()[1:7]).To(Equal([]byte{3, 0, 0, 0, 0, 0})) - }) - - It("errors when PacketNumber was not set", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumberLen: protocol.PacketNumberLen1, - Entropy: 0xAD, - } - err := frame.Write(b, 0) - Expect(err).To(MatchError(errPacketNumberNotSet)) - }) - - It("errors when PacketNumberLen was not set", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumber: 13, - Entropy: 0xAD, - } - err := frame.Write(b, 0) - Expect(err).To(MatchError(errPacketNumberLenNotSet)) - }) - - It("errors when the LeastUnackedDelta would be negative", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumber: 5, PacketNumberLen: protocol.PacketNumberLen1, } - err := frame.Write(b, 0) - Expect(err).To(MatchError(errLeastUnackedHigherThanPacketNumber)) - }) - - Context("LeastUnackedDelta length", func() { - It("writes a 1-byte LeastUnackedDelta", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumber: 13, - PacketNumberLen: protocol.PacketNumberLen1, - } - frame.Write(b, 0) - Expect(b.Len()).To(Equal(3)) - Expect(b.Bytes()[2]).To(Equal(uint8(3))) - }) - - It("writes a 2-byte LeastUnackedDelta", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 0x10, - PacketNumber: 0x1300, - PacketNumberLen: protocol.PacketNumberLen2, - } - frame.Write(b, 0) - Expect(b.Len()).To(Equal(4)) - Expect(b.Bytes()[2:4]).To(Equal([]byte{0xF0, 0x12})) - }) - - It("writes a 4-byte LeastUnackedDelta", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 0x1000, - PacketNumber: 0x12345678, - PacketNumberLen: protocol.PacketNumberLen4, - } - frame.Write(b, 0) - Expect(b.Len()).To(Equal(6)) - Expect(b.Bytes()[2:6]).To(Equal([]byte{0x78, 0x46, 0x34, 0x12})) - }) - - It("writes a 6-byte LeastUnackedDelta", func() { - b := &bytes.Buffer{} - frame := &StopWaitingFrame{ - LeastUnacked: 0x10, - PacketNumber: 0x123456789ABC, - PacketNumberLen: protocol.PacketNumberLen6, - } - frame.Write(b, 0) - Expect(b.Len()).To(Equal(8)) - Expect(b.Bytes()[2:8]).To(Equal([]byte{0xAC, 0x9A, 0x78, 0x56, 0x34, 0x12})) - }) - }) - }) - - Context("minLength", func() { - It("calculates the right minLength", func() { - for _, length := range []protocol.PacketNumberLen{protocol.PacketNumberLen1, protocol.PacketNumberLen2, protocol.PacketNumberLen4, protocol.PacketNumberLen6} { - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumberLen: length, - } - Expect(frame.MinLength(protocol.Version33)).To(Equal(protocol.ByteCount(length + 2))) - } - }) - - It("calculates the right minLength, for QUIC version 34", func() { - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumberLen: protocol.PacketNumberLen4, - } - Expect(frame.MinLength(protocol.Version34)).To(Equal(protocol.ByteCount(4 + 1))) - }) - - It("errors when packetNumberLen is not set", func() { - frame := &StopWaitingFrame{ - LeastUnacked: 10, - } - _, err := frame.MinLength(0) - Expect(err).To(MatchError(errPacketNumberLenNotSet)) - }) - }) - - Context("self consistency", func() { - It("reads a stop waiting frame that it wrote", func() { - packetNumber := protocol.PacketNumber(13) - frame := &StopWaitingFrame{ - LeastUnacked: 10, - PacketNumber: packetNumber, - Entropy: 0xAC, - PacketNumberLen: protocol.PacketNumberLen4, - } - b := &bytes.Buffer{} frame.Write(b, 0) - readframe, err := ParseStopWaitingFrame(bytes.NewReader(b.Bytes()), packetNumber, protocol.PacketNumberLen4, protocol.Version33) - Expect(err).ToNot(HaveOccurred()) - Expect(readframe.Entropy).To(Equal(frame.Entropy)) - Expect(readframe.LeastUnacked).To(Equal(frame.LeastUnacked)) + Expect(b.Len()).To(Equal(3)) + Expect(b.Bytes()[2]).To(Equal(uint8(3))) + }) + + It("writes a 2-byte LeastUnackedDelta", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 0x10, + PacketNumber: 0x1300, + PacketNumberLen: protocol.PacketNumberLen2, + } + frame.Write(b, 0) + Expect(b.Len()).To(Equal(4)) + Expect(b.Bytes()[2:4]).To(Equal([]byte{0xF0, 0x12})) + }) + + It("writes a 4-byte LeastUnackedDelta", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 0x1000, + PacketNumber: 0x12345678, + PacketNumberLen: protocol.PacketNumberLen4, + } + frame.Write(b, 0) + Expect(b.Len()).To(Equal(6)) + Expect(b.Bytes()[2:6]).To(Equal([]byte{0x78, 0x46, 0x34, 0x12})) + }) + + It("writes a 6-byte LeastUnackedDelta", func() { + b := &bytes.Buffer{} + frame := &StopWaitingFrame{ + LeastUnacked: 0x10, + PacketNumber: 0x123456789ABC, + PacketNumberLen: protocol.PacketNumberLen6, + } + frame.Write(b, 0) + Expect(b.Len()).To(Equal(8)) + Expect(b.Bytes()[2:8]).To(Equal([]byte{0xAC, 0x9A, 0x78, 0x56, 0x34, 0x12})) }) }) }) + + Context("minLength", func() { + It("calculates the right minLength", func() { + for _, length := range []protocol.PacketNumberLen{protocol.PacketNumberLen1, protocol.PacketNumberLen2, protocol.PacketNumberLen4, protocol.PacketNumberLen6} { + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumberLen: length, + } + Expect(frame.MinLength(protocol.Version33)).To(Equal(protocol.ByteCount(length + 2))) + } + }) + + It("calculates the right minLength, for QUIC version 34", func() { + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumberLen: protocol.PacketNumberLen4, + } + Expect(frame.MinLength(protocol.Version34)).To(Equal(protocol.ByteCount(4 + 1))) + }) + + It("errors when packetNumberLen is not set", func() { + frame := &StopWaitingFrame{ + LeastUnacked: 10, + } + _, err := frame.MinLength(0) + Expect(err).To(MatchError(errPacketNumberLenNotSet)) + }) + }) + + Context("self consistency", func() { + It("reads a stop waiting frame that it wrote", func() { + packetNumber := protocol.PacketNumber(13) + frame := &StopWaitingFrame{ + LeastUnacked: 10, + PacketNumber: packetNumber, + Entropy: 0xAC, + PacketNumberLen: protocol.PacketNumberLen4, + } + b := &bytes.Buffer{} + frame.Write(b, 0) + readframe, err := ParseStopWaitingFrame(bytes.NewReader(b.Bytes()), packetNumber, protocol.PacketNumberLen4, protocol.Version33) + Expect(err).ToNot(HaveOccurred()) + Expect(readframe.Entropy).To(Equal(frame.Entropy)) + Expect(readframe.LeastUnacked).To(Equal(frame.LeastUnacked)) + }) + }) }) diff --git a/frames/stream_frame.go b/frames/stream_frame.go index cfdb73a0..88dabe6d 100644 --- a/frames/stream_frame.go +++ b/frames/stream_frame.go @@ -3,6 +3,7 @@ package frames import ( "bytes" "errors" + "io" "io/ioutil" "github.com/lucas-clemente/quic-go/protocol" @@ -73,7 +74,7 @@ func ParseStreamFrame(r *bytes.Reader) (*StreamFrame, error) { } } else { frame.Data = make([]byte, dataLen) - if _, err := r.Read(frame.Data); err != nil { + if _, err := io.ReadFull(r, frame.Data); err != nil { return nil, err } } diff --git a/frames/stream_frame_test.go b/frames/stream_frame_test.go index a00bbeb3..11eb5ad3 100644 --- a/frames/stream_frame_test.go +++ b/frames/stream_frame_test.go @@ -53,6 +53,16 @@ var _ = Describe("StreamFrame", func() { _, err := ParseStreamFrame(b) Expect(err).To(MatchError(qerr.Error(qerr.InvalidStreamData, "data len too large"))) }) + + It("errors on EOFs", func() { + data := []byte{0xa0, 0x1, 0x06, 0x00, 'f', 'o', 'o', 'b', 'a', 'r'} + _, err := ParseStreamFrame(bytes.NewReader(data)) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseStreamFrame(bytes.NewReader(data[0:i])) + Expect(err).To(HaveOccurred()) + } + }) }) Context("when writing", func() { diff --git a/frames/window_update_frame_test.go b/frames/window_update_frame_test.go index b2487c2b..602b0fad 100644 --- a/frames/window_update_frame_test.go +++ b/frames/window_update_frame_test.go @@ -18,6 +18,16 @@ var _ = Describe("WindowUpdateFrame", func() { Expect(frame.ByteOffset).To(Equal(protocol.ByteCount(0xDECAFBAD11223344))) Expect(b.Len()).To(Equal(0)) }) + + It("errors on EOFs", func() { + data := []byte{0x04, 0xEF, 0xBE, 0xAD, 0xDE, 0x44, 0x33, 0x22, 0x11, 0xAD, 0xFB, 0xCA, 0xDE} + _, err := ParseWindowUpdateFrame(bytes.NewReader(data)) + Expect(err).NotTo(HaveOccurred()) + for i := range data { + _, err := ParseWindowUpdateFrame(bytes.NewReader(data[0:i])) + Expect(err).To(HaveOccurred()) + } + }) }) Context("when writing", func() {