Skip to content

Commit 149728f

Browse files
committed
Handle Header.PaddingSize in PacketFactoryCopy
PacketFactoryCopy.NewPacket does not handle case when padding size is set in Header.PaddingSize and no padding is in payload. It would try to remove it and either it would create broken packet or return error. It should not do this when PaddingSize field is set.
1 parent fa5b35e commit 149728f

File tree

2 files changed

+37
-8
lines changed

2 files changed

+37
-8
lines changed

internal/rtpbuffer/packet_factory.go

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -102,15 +102,19 @@ func (m *PacketFactoryCopy) NewPacket(
102102
// Rewrite the sequence number.
103103
retainablePacket.header.SequenceNumber = m.rtxSequencer.NextSequenceNumber()
104104
// Remove padding if present.
105-
if retainablePacket.header.Padding && retainablePacket.payload != nil && len(retainablePacket.payload) > 0 {
106-
paddingLength := int(retainablePacket.payload[len(retainablePacket.payload)-1])
107-
retainablePacket.header.Padding = false
108-
109-
if paddingLength > len(retainablePacket.payload) {
110-
return nil, errPaddingOverflow
105+
if retainablePacket.header.Padding {
106+
// Older versions of pion/rtp didn't have the Header.PaddingSize field and as a workaround
107+
// users had to add padding to the payload. We need to handle this case here.
108+
if retainablePacket.header.PaddingSize == 0 && len(retainablePacket.payload) > 0 {
109+
paddingLength := int(retainablePacket.payload[len(retainablePacket.payload)-1])
110+
if paddingLength > len(retainablePacket.payload) {
111+
return nil, errPaddingOverflow
112+
}
113+
retainablePacket.payload = (*retainablePacket.buffer)[:len(retainablePacket.payload)-paddingLength]
111114
}
112115

113-
retainablePacket.payload = (*retainablePacket.buffer)[:len(retainablePacket.payload)-paddingLength]
116+
retainablePacket.header.Padding = false
117+
retainablePacket.header.PaddingSize = 0
114118
}
115119
}
116120

internal/rtpbuffer/rtpbuffer_test.go

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ func TestRTPBuffer_Padding(t *testing.T) {
226226
require.NoError(t, err)
227227
require.Equal(t, uint16(1), sb.size)
228228

229-
t.Run("valid padding is stripped", func(t *testing.T) {
229+
t.Run("valid padding in payload is stripped", func(t *testing.T) {
230230
origPayload := []byte{116, 101, 115, 116}
231231
expected := []byte{0, 1, 116, 101, 115, 116}
232232

@@ -239,6 +239,7 @@ func TestRTPBuffer_Padding(t *testing.T) {
239239
pkt, err := pm.NewPacket(&rtp.Header{
240240
SequenceNumber: 1,
241241
Padding: true,
242+
PaddingSize: 0,
242243
}, padded, 1, 1)
243244
require.NoError(t, err)
244245

@@ -255,6 +256,30 @@ func TestRTPBuffer_Padding(t *testing.T) {
255256
require.Equal(t, expected, actual, "payload content after trimming")
256257
})
257258

259+
t.Run("valid paddingsize in header is cleared", func(t *testing.T) {
260+
origPayload := []byte{116, 101, 115, 116}
261+
expected := []byte{0, 1, 116, 101, 115, 116}
262+
263+
pkt, err := pm.NewPacket(&rtp.Header{
264+
SequenceNumber: 1,
265+
Padding: true,
266+
PaddingSize: 120,
267+
}, origPayload, 1, 1)
268+
require.NoError(t, err)
269+
270+
sb.Add(pkt)
271+
272+
retrieved := sb.Get(1)
273+
require.NotNil(t, retrieved)
274+
defer retrieved.Release()
275+
276+
require.False(t, retrieved.Header().Padding, "P-bit should be cleared after trimming")
277+
278+
actual := retrieved.Payload()
279+
require.Equal(t, len(expected), len(actual), "payload length after trimming")
280+
require.Equal(t, expected, actual, "payload content after trimming")
281+
})
282+
258283
t.Run("overflow padding returns io.ErrShortBuffer", func(t *testing.T) {
259284
overflow := []byte{0, 1, 200}
260285

0 commit comments

Comments
 (0)