summaryrefslogtreecommitdiff
path: root/chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc')
-rw-r--r--chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc176
1 files changed, 174 insertions, 2 deletions
diff --git a/chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc b/chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
index 31baf4e767a..f64b537a522 100644
--- a/chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
+++ b/chromium/third_party/webrtc/modules/rtp_rtcp/source/fec_receiver_unittest.cc
@@ -16,7 +16,9 @@
#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/base/scoped_ptr.h"
#include "webrtc/modules/rtp_rtcp/interface/fec_receiver.h"
+#include "webrtc/modules/rtp_rtcp/interface/rtp_header_parser.h"
#include "webrtc/modules/rtp_rtcp/mocks/mock_rtp_rtcp.h"
+#include "webrtc/modules/rtp_rtcp/source/byte_io.h"
#include "webrtc/modules/rtp_rtcp/source/fec_test_helper.h"
#include "webrtc/modules/rtp_rtcp/source/forward_error_correction.h"
@@ -81,6 +83,11 @@ class ReceiverFecTest : public ::testing::Test {
delete red_packet;
}
+ void InjectGarbagePacketLength(size_t fec_garbage_offset);
+ static void SurvivesMaliciousPacket(const uint8_t* data,
+ size_t length,
+ uint8_t ulpfec_payload_type);
+
MockRtpData rtp_data_callback_;
rtc::scoped_ptr<ForwardErrorCorrection> fec_;
rtc::scoped_ptr<FecReceiver> receiver_fec_;
@@ -104,8 +111,7 @@ TEST_F(ReceiverFecTest, TwoMediaOneFec) {
// Recovery
std::list<RtpPacket*>::iterator it = media_rtp_packets.begin();
- std::list<RtpPacket*>::iterator media_it = media_rtp_packets.begin();
- BuildAndAddRedMediaPacket(*media_it);
+ BuildAndAddRedMediaPacket(*it);
VerifyReconstructedMediaPacket(*it, 1);
EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
// Drop one media packet.
@@ -123,6 +129,44 @@ TEST_F(ReceiverFecTest, TwoMediaOneFec) {
DeletePackets(&media_packets);
}
+void ReceiverFecTest::InjectGarbagePacketLength(size_t fec_garbage_offset) {
+ EXPECT_CALL(rtp_data_callback_, OnRecoveredPacket(_, _))
+ .WillRepeatedly(Return(true));
+
+ const unsigned int kNumFecPackets = 1u;
+ std::list<RtpPacket*> media_rtp_packets;
+ std::list<Packet*> media_packets;
+ GenerateFrame(2, 0, &media_rtp_packets, &media_packets);
+ std::list<Packet*> fec_packets;
+ GenerateFEC(&media_packets, &fec_packets, kNumFecPackets);
+ ByteWriter<uint16_t>::WriteBigEndian(
+ &fec_packets.front()->data[fec_garbage_offset], 0x4711);
+
+ // Inject first media packet, then first FEC packet, skipping the second media
+ // packet to cause a recovery from the FEC packet.
+ BuildAndAddRedMediaPacket(media_rtp_packets.front());
+ BuildAndAddRedFecPacket(fec_packets.front());
+ EXPECT_EQ(0, receiver_fec_->ProcessReceivedFec());
+
+ FecPacketCounter counter = receiver_fec_->GetPacketCounter();
+ EXPECT_EQ(2u, counter.num_packets);
+ EXPECT_EQ(1u, counter.num_fec_packets);
+ EXPECT_EQ(0u, counter.num_recovered_packets);
+
+ DeletePackets(&media_packets);
+}
+
+TEST_F(ReceiverFecTest, InjectGarbageFecHeaderLengthRecovery) {
+ // Byte offset 8 is the 'length recovery' field of the FEC header.
+ InjectGarbagePacketLength(8);
+}
+
+TEST_F(ReceiverFecTest, InjectGarbageFecLevelHeaderProtectionLength) {
+ // Byte offset 10 is the 'protection length' field in the first FEC level
+ // header.
+ InjectGarbagePacketLength(10);
+}
+
TEST_F(ReceiverFecTest, TwoMediaTwoFec) {
const unsigned int kNumFecPackets = 2u;
std::list<RtpPacket*> media_rtp_packets;
@@ -362,4 +406,132 @@ TEST_F(ReceiverFecTest, OldFecPacketDropped) {
DeletePackets(&media_packets);
}
+void ReceiverFecTest::SurvivesMaliciousPacket(const uint8_t* data,
+ size_t length,
+ uint8_t ulpfec_payload_type) {
+ webrtc::RTPHeader header;
+ rtc::scoped_ptr<webrtc::RtpHeaderParser> parser(
+ webrtc::RtpHeaderParser::Create());
+ ASSERT_TRUE(parser->Parse(data, length, &header));
+
+ webrtc::NullRtpData null_callback;
+ rtc::scoped_ptr<webrtc::FecReceiver> receiver_fec(
+ webrtc::FecReceiver::Create(&null_callback));
+
+ receiver_fec->AddReceivedRedPacket(header, data, length, ulpfec_payload_type);
+}
+
+TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSet) {
+ const uint8_t kTruncatedPacket[] = {0x80,
+ 0x2a,
+ 0x68,
+ 0x71,
+ 0x29,
+ 0xa1,
+ 0x27,
+ 0x3a,
+ 0x29,
+ 0x12,
+ 0x2a,
+ 0x98,
+ 0xe0,
+ 0x29};
+
+ SurvivesMaliciousPacket(kTruncatedPacket, sizeof(kTruncatedPacket), 100);
+}
+
+TEST_F(ReceiverFecTest, TruncatedPacketWithFBitSetEndingAfterFirstRedHeader) {
+ const uint8_t kPacket[] = {0x89,
+ 0x27,
+ 0x3a,
+ 0x83,
+ 0x27,
+ 0x3a,
+ 0x3a,
+ 0xf3,
+ 0x67,
+ 0xbe,
+ 0x2a,
+ 0xa9,
+ 0x27,
+ 0x54,
+ 0x3a,
+ 0x3a,
+ 0x2a,
+ 0x67,
+ 0x3a,
+ 0xf3,
+ 0x67,
+ 0xbe,
+ 0x2a,
+ 0x27,
+ 0xe6,
+ 0xf6,
+ 0x03,
+ 0x3e,
+ 0x29,
+ 0x27,
+ 0x21,
+ 0x27,
+ 0x2a,
+ 0x29,
+ 0x21,
+ 0x4b,
+ 0x29,
+ 0x3a,
+ 0x28,
+ 0x29,
+ 0xbf,
+ 0x29,
+ 0x2a,
+ 0x26,
+ 0x29,
+ 0xae,
+ 0x27,
+ 0xa6,
+ 0xf6,
+ 0x00,
+ 0x03,
+ 0x3e};
+ SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100);
+}
+
+TEST_F(ReceiverFecTest, TruncatedPacketWithoutDataPastFirstBlock) {
+ const uint8_t kPacket[] = {0x82,
+ 0x38,
+ 0x92,
+ 0x38,
+ 0x92,
+ 0x38,
+ 0xde,
+ 0x2a,
+ 0x11,
+ 0xc8,
+ 0xa3,
+ 0xc4,
+ 0x82,
+ 0x38,
+ 0x2a,
+ 0x21,
+ 0x2a,
+ 0x28,
+ 0x92,
+ 0x38,
+ 0x92,
+ 0x00,
+ 0x00,
+ 0x0a,
+ 0x3a,
+ 0xc8,
+ 0xa3,
+ 0x3a,
+ 0x27,
+ 0xc4,
+ 0x2a,
+ 0x21,
+ 0x2a,
+ 0x28};
+ SurvivesMaliciousPacket(kPacket, sizeof(kPacket), 100);
+}
+
} // namespace webrtc