diff --git a/webrtc/modules/video_coding/packet_buffer.cc b/webrtc/modules/video_coding/packet_buffer.cc index 7b01e4cb27..452e762b9f 100644 --- a/webrtc/modules/video_coding/packet_buffer.cc +++ b/webrtc/modules/video_coding/packet_buffer.cc @@ -40,7 +40,6 @@ PacketBuffer::PacketBuffer(Clock* clock, size_(start_buffer_size), max_size_(max_buffer_size), first_seq_num_(0), - last_seq_num_(0), first_packet_received_(false), is_cleared_to_first_seq_num_(false), data_buffer_(start_buffer_size), @@ -65,7 +64,6 @@ bool PacketBuffer::InsertPacket(VCMPacket* packet) { if (!first_packet_received_) { first_seq_num_ = seq_num; - last_seq_num_ = seq_num; first_packet_received_ = true; } else if (AheadOf(first_seq_num_, seq_num)) { // If we have explicitly cleared past this packet then it's old, @@ -100,9 +98,6 @@ bool PacketBuffer::InsertPacket(VCMPacket* packet) { } } - if (AheadOf(seq_num, last_seq_num_)) - last_seq_num_ = seq_num; - sequence_buffer_[index].frame_begin = packet->is_first_packet_in_frame; sequence_buffer_[index].frame_end = packet->markerBit; sequence_buffer_[index].seq_num = packet->seqNum; @@ -186,6 +181,8 @@ bool PacketBuffer::PotentialNewFrame(uint16_t seq_num) const { return true; if (!sequence_buffer_[prev_index].used) return false; + if (sequence_buffer_[prev_index].frame_created) + return false; if (sequence_buffer_[prev_index].seq_num != static_cast(sequence_buffer_[index].seq_num - 1)) { return false; diff --git a/webrtc/modules/video_coding/packet_buffer.h b/webrtc/modules/video_coding/packet_buffer.h index da7e80ffaa..001f8bd89d 100644 --- a/webrtc/modules/video_coding/packet_buffer.h +++ b/webrtc/modules/video_coding/packet_buffer.h @@ -126,9 +126,6 @@ class PacketBuffer { // The fist sequence number currently in the buffer. uint16_t first_seq_num_ GUARDED_BY(crit_); - // The last sequence number currently in the buffer. - uint16_t last_seq_num_ GUARDED_BY(crit_); - // If the packet buffer has received its first packet. bool first_packet_received_ GUARDED_BY(crit_); diff --git a/webrtc/modules/video_coding/video_packet_buffer_unittest.cc b/webrtc/modules/video_coding/video_packet_buffer_unittest.cc index ddb088c63e..d938b8b958 100644 --- a/webrtc/modules/video_coding/video_packet_buffer_unittest.cc +++ b/webrtc/modules/video_coding/video_packet_buffer_unittest.cc @@ -468,5 +468,14 @@ TEST_F(TestPacketBuffer, DontLeakPayloadData) { EXPECT_FALSE(Insert(2 + kMaxSize, kKeyFrame, kFirst, kNotLast, 5, data4)); } +TEST_F(TestPacketBuffer, ContinuousSeqNumDoubleMarkerBit) { + Insert(2, kKeyFrame, kNotFirst, kNotLast); + Insert(1, kKeyFrame, kFirst, kLast); + frames_from_callback_.clear(); + Insert(3, kKeyFrame, kNotFirst, kLast); + + EXPECT_EQ(0UL, frames_from_callback_.size()); +} + } // namespace video_coding } // namespace webrtc diff --git a/webrtc/test/fuzzers/BUILD.gn b/webrtc/test/fuzzers/BUILD.gn index 141dcfe514..224b212c11 100644 --- a/webrtc/test/fuzzers/BUILD.gn +++ b/webrtc/test/fuzzers/BUILD.gn @@ -124,6 +124,16 @@ webrtc_fuzzer_test("flexfec_receiver_fuzzer") { libfuzzer_options = [ "max_len=2000" ] } +webrtc_fuzzer_test("packet_buffer_fuzzer") { + sources = [ + "packet_buffer_fuzzer.cc", + ] + deps = [ + "../../modules/video_coding/", + ] + libfuzzer_options = [ "max_len=2000" ] +} + webrtc_fuzzer_test("rtcp_receiver_fuzzer") { sources = [ "rtcp_receiver_fuzzer.cc", diff --git a/webrtc/test/fuzzers/packet_buffer_fuzzer.cc b/webrtc/test/fuzzers/packet_buffer_fuzzer.cc new file mode 100644 index 0000000000..099fe21fc2 --- /dev/null +++ b/webrtc/test/fuzzers/packet_buffer_fuzzer.cc @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/video_coding/packet_buffer.h" +#include "webrtc/system_wrappers/include/clock.h" + +namespace webrtc { + +namespace { +class NullCallback : public video_coding::OnReceivedFrameCallback { + void OnReceivedFrame(std::unique_ptr frame) {} +}; +} // namespace + +void FuzzOneInput(const uint8_t* data, size_t size) { + // Two bytes for the sequence number, + // one byte for |is_first_packet_in_frame| and |markerBit|. + constexpr size_t kMinDataNeeded = 3; + if (size < kMinDataNeeded) { + return; + } + + VCMPacket packet; + NullCallback callback; + SimulatedClock clock(0); + rtc::scoped_refptr packet_buffer( + video_coding::PacketBuffer::Create(&clock, 8, 1024, &callback)); + + size_t i = kMinDataNeeded; + while (i < size) { + memcpy(&packet.seqNum, &data[i - kMinDataNeeded], 2); + packet.is_first_packet_in_frame = data[i] & 1; + packet.markerBit = data[i] & 2; + packet_buffer->InsertPacket(&packet); + i += kMinDataNeeded; + } +} + +} // namespace webrtc