diff --git a/transport_layer_cc.go b/transport_layer_cc.go index 3c0e220..5df05ea 100644 --- a/transport_layer_cc.go +++ b/transport_layer_cc.go @@ -533,22 +533,23 @@ func (t *TransportLayerCC) Unmarshal(rawPacket []byte) error { if err != nil { return err } + packetNumberToProcess := min(int(t.PacketStatusCount-processedPacketNum), len(packetStatus.SymbolList)) if packetStatus.SymbolSize == TypeTCCSymbolSizeOneBit { - for j := 0; j < len(packetStatus.SymbolList); j++ { + for j := range packetNumberToProcess { if packetStatus.SymbolList[j] == TypeTCCPacketReceivedSmallDelta { t.RecvDeltas = append(t.RecvDeltas, &RecvDelta{Type: TypeTCCPacketReceivedSmallDelta}) } } } if packetStatus.SymbolSize == TypeTCCSymbolSizeTwoBit { - for j := 0; j < len(packetStatus.SymbolList); j++ { + for j := range packetNumberToProcess { if packetStatus.SymbolList[j] == TypeTCCPacketReceivedSmallDelta || packetStatus.SymbolList[j] == TypeTCCPacketReceivedLargeDelta { t.RecvDeltas = append(t.RecvDeltas, &RecvDelta{Type: packetStatus.SymbolList[j]}) } } } - processedPacketNum += uint16(len(packetStatus.SymbolList)) //nolint:gosec // G115 + processedPacketNum += uint16(packetNumberToProcess) //nolint:gosec // bounded by remaining packet count } packetStatusPos += packetStatusChunkLength t.PacketChunks = append(t.PacketChunks, iPacketStatus) diff --git a/transport_layer_cc_test.go b/transport_layer_cc_test.go index e7897db..b5954ea 100644 --- a/transport_layer_cc_test.go +++ b/transport_layer_cc_test.go @@ -4,6 +4,8 @@ package rtcp import ( + "encoding/binary" + "fmt" "testing" "github.com/stretchr/testify/assert" @@ -1213,3 +1215,31 @@ func TestTransportLayerCC_LengthOverflow(t *testing.T) { assert.ErrorIs(t, err, errBadLength) assert.Nil(t, data) } + +func TestTransportLayerCC_UnmarshalUnusedVector(t *testing.T) { + for _, symbol := range []uint16{0xbfff, 0xeaaa} { + for _, missing := range []uint16{0, 65530} { + t.Run(fmt.Sprintf("%x/%d", symbol, missing), func(t *testing.T) { + header := [20]byte{0x8f, 205, 0, 5} + data := header[:] + binary.BigEndian.PutUint16(data[14:16], missing+1) + for remaining := missing; remaining > 0; { + count := min(remaining, 8191) + data = binary.BigEndian.AppendUint16(data, count) + remaining -= count + } + data = binary.BigEndian.AppendUint16(data, symbol) + data = append(data, 0, 0) + if missing > 0 { + data = append(data, 0, 0) + data[3] = 10 + } + + var packet TransportLayerCC + assert.NoError(t, packet.Unmarshal(data)) + assert.Len(t, packet.RecvDeltas, 1) + assert.Equal(t, missing+1, packet.PacketStatusCount) + }) + } + } +}