diff --git a/frames/ack_frame_new.go b/frames/ack_frame_new.go index 918b1a3d0..171defe1f 100644 --- a/frames/ack_frame_new.go +++ b/frames/ack_frame_new.go @@ -9,8 +9,12 @@ import ( "github.com/lucas-clemente/quic-go/utils" ) -// ErrInvalidAckRanges occurs when a client sends inconsistent ACK ranges -var ErrInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges") +var ( + // ErrInvalidAckRanges occurs when a client sends inconsistent ACK ranges + ErrInvalidAckRanges = errors.New("AckFrame: ACK frame contains invalid ACK ranges") + // ErrInvalidFirstAckRange occurs when the first ACK range contains no packets + ErrInvalidFirstAckRange = errors.New("AckFrame: ACK frame has invalid first ACK range") +) var ( errInconsistentAckLargestAcked = errors.New("internal inconsistency: LargestAcked does not match ACK ranges") @@ -75,6 +79,9 @@ func ParseAckFrameNew(r *bytes.Reader, version protocol.VersionNumber) (*AckFram if err != nil { return nil, err } + if ackBlockLength < 1 { + return nil, ErrInvalidFirstAckRange + } if ackBlockLength > largestAcked { return nil, ErrInvalidAckRanges diff --git a/frames/ack_frame_new_test.go b/frames/ack_frame_new_test.go index b4dbfa61b..8f5f544f2 100644 --- a/frames/ack_frame_new_test.go +++ b/frames/ack_frame_new_test.go @@ -30,10 +30,21 @@ var _ = Describe("AckFrame", func() { }) It("parses a frame with a 48 bit packet number", func() { - b := bytes.NewReader([]byte{0x4c, 0x37, 0x13, 0xad, 0xfb, 0xca, 0xde, 0x0, 0x0, 0x0, 0x1, 0, 0, 0, 0, 0}) - frame, err := ParseAckFrameNew(b, protocol.Version34) + b := bytes.NewReader([]byte{0x4c, 0x37, 0x13, 0xad, 0xfb, 0xca, 0xde, 0x0, 0x0, 0x5, 0x1, 0, 0, 0, 0, 0}) + frame, err := ParseAckFrameNew(b, 0) Expect(err).ToNot(HaveOccurred()) Expect(frame.LargestAcked).To(Equal(protocol.PacketNumber(0xdecafbad1337))) + Expect(frame.LowestAcked).To(Equal(protocol.PacketNumber(0xdecafbad1337 - 5 + 1))) + Expect(frame.HasMissingRanges()).To(BeFalse()) + Expect(b.Len()).To(BeZero()) + }) + + It("parses a frame with 1 ACKed packet", func() { + b := bytes.NewReader([]byte{0x40, 0x10, 0x8e, 0x0, 0x1, 0x0}) + frame, err := ParseAckFrameNew(b, 0) + Expect(err).ToNot(HaveOccurred()) + Expect(frame.LargestAcked).To(Equal(protocol.PacketNumber(0x10))) + Expect(frame.LowestAcked).To(Equal(protocol.PacketNumber(0x10))) Expect(frame.HasMissingRanges()).To(BeFalse()) Expect(b.Len()).To(BeZero()) }) @@ -62,6 +73,12 @@ var _ = Describe("AckFrame", func() { Expect(err).To(MatchError(ErrInvalidAckRanges)) }) + It("errors when the first ACK range is empty", func() { + b := bytes.NewReader([]byte{0x40, 0x9, 0x8e, 0x0, 0x0, 0x1, 0}) + _, err := ParseAckFrameNew(b, 0) + Expect(err).To(MatchError(ErrInvalidFirstAckRange)) + }) + Context("ACK blocks", func() { It("parses a frame with one ACK block", func() { b := bytes.NewReader([]byte{0x60, 0x18, 0x94, 0x1, 0x1, 0x3, 0x2, 0x10, 0x2, 0x1, 0x5c, 0xd5, 0x0, 0x0, 0x0, 0x95, 0x0})