Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions srtcore/buffer_rcv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -276,10 +276,10 @@ int CRcvBuffer::dropMessage(int32_t seqnolo, int32_t seqnohi, int32_t msgno, Dro
// Drop by packet seqno range to also wipe those packets that do not exist in the buffer.
const int offset_a = CSeqNo::seqoff(m_iStartSeqNo, seqnolo);
const int offset_b = CSeqNo::seqoff(m_iStartSeqNo, seqnohi);
if (offset_b < 0)
if (offset_b < 0 || offset_a >= (int) m_szSize)
{
LOGC(rbuflog.Debug, log << "CRcvBuffer.dropMessage(): nothing to drop. Requested [" << seqnolo << "; "
<< seqnohi << "]. Buffer start " << m_iStartSeqNo << ".");
<< seqnohi << "]. Buffer start " << m_iStartSeqNo << " size " << m_szSize << ".");
return 0;
}

Expand Down
28 changes: 28 additions & 0 deletions test/test_buffer_rcv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,34 @@ TEST_F(CRcvBufferReadMsg, PacketDropBySeqNo)
EXPECT_EQ(m_unit_queue->size(), m_unit_queue->capacity());
}

// Drop ranges whose low seqno is already past the buffer end must be a
// no-op. Without the offset_a >= m_szSize guard, incPos() wraps modulo
// m_szSize and the loop walks legitimate entries -- mirroring the DoS
// shape of a reversed range, just triggered from the other side.
TEST_F(CRcvBufferReadMsg, PacketDropLoPastBufferEnd)
{
EXPECT_EQ(addMessage(1, 1, m_init_seqno), 0);
EXPECT_EQ(addMessage(1, 2, CSeqNo::incseq(m_init_seqno)), 0);

auto& rcv_buffer = *m_rcv_buffer.get();
EXPECT_TRUE(hasAvailablePackets());

// Buffer size is m_buff_size_pkts (16); pick a range that begins
// well past the last valid slot.
const int32_t lo = m_init_seqno + 2 * m_buff_size_pkts;
const int32_t hi = lo + 4;
EXPECT_EQ(rcv_buffer.dropMessage(lo, hi, SRT_MSGNO_NONE, CRcvBuffer::DROP_EXISTING), 0);

// The two packets we inserted must still be present and readable.
EXPECT_TRUE(hasAvailablePackets());
EXPECT_TRUE(rcv_buffer.isRcvDataReady());
array<char, m_payload_sz> buff;
EXPECT_EQ(readMessage(buff.data(), buff.size()), (int) m_payload_sz);
EXPECT_TRUE(verifyPayload(buff.data(), m_payload_sz, m_init_seqno));
EXPECT_EQ(readMessage(buff.data(), buff.size()), (int) m_payload_sz);
EXPECT_TRUE(verifyPayload(buff.data(), m_payload_sz, CSeqNo::incseq(m_init_seqno)));
}

// Test dropping a message by message number and sequence number.
TEST_F(CRcvBufferReadMsg, PacketDropByMsgNoSeqNo)
{
Expand Down
Loading