summaryrefslogtreecommitdiffstats
path: root/third_party/libwebrtc/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/libwebrtc/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc')
-rw-r--r--third_party/libwebrtc/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc154
1 files changed, 154 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
new file mode 100644
index 0000000000..fdb4aa5f3c
--- /dev/null
+++ b/third_party/libwebrtc/test/fuzzers/rtp_frame_reference_finder_fuzzer.cc
@@ -0,0 +1,154 @@
+/*
+ * Copyright (c) 2018 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 <memory>
+
+#include "api/rtp_packet_infos.h"
+#include "modules/video_coding/frame_object.h"
+#include "modules/video_coding/rtp_frame_reference_finder.h"
+
+namespace webrtc {
+
+namespace {
+class DataReader {
+ public:
+ DataReader(const uint8_t* data, size_t size) : data_(data), size_(size) {}
+
+ template <typename T>
+ void CopyTo(T* object) {
+ static_assert(std::is_pod<T>(), "");
+ uint8_t* destination = reinterpret_cast<uint8_t*>(object);
+ size_t object_size = sizeof(T);
+ size_t num_bytes = std::min(size_ - offset_, object_size);
+ memcpy(destination, data_ + offset_, num_bytes);
+ offset_ += num_bytes;
+
+ // If we did not have enough data, fill the rest with 0.
+ object_size -= num_bytes;
+ memset(destination + num_bytes, 0, object_size);
+ }
+
+ template <typename T>
+ T GetNum() {
+ T res;
+ if (offset_ + sizeof(res) < size_) {
+ memcpy(&res, data_ + offset_, sizeof(res));
+ offset_ += sizeof(res);
+ return res;
+ }
+
+ offset_ = size_;
+ return T(0);
+ }
+
+ bool MoreToRead() { return offset_ < size_; }
+
+ private:
+ const uint8_t* data_;
+ size_t size_;
+ size_t offset_ = 0;
+};
+
+absl::optional<RTPVideoHeader::GenericDescriptorInfo>
+GenerateGenericFrameDependencies(DataReader* reader) {
+ absl::optional<RTPVideoHeader::GenericDescriptorInfo> result;
+ uint8_t flags = reader->GetNum<uint8_t>();
+ if (flags & 0b1000'0000) {
+ // i.e. with 50% chance there are no generic dependencies.
+ // in such case codec-specfic code path of the RtpFrameReferenceFinder will
+ // be validated.
+ return result;
+ }
+
+ result.emplace();
+ result->frame_id = reader->GetNum<int32_t>();
+ result->spatial_index = (flags & 0b0111'0000) >> 4;
+ result->temporal_index = (flags & 0b0000'1110) >> 1;
+
+ // Larger than supported by the RtpFrameReferenceFinder.
+ int num_diffs = (reader->GetNum<uint8_t>() % 16);
+ for (int i = 0; i < num_diffs; ++i) {
+ result->dependencies.push_back(result->frame_id -
+ (reader->GetNum<uint16_t>() % (1 << 14)));
+ }
+
+ return result;
+}
+} // namespace
+
+void FuzzOneInput(const uint8_t* data, size_t size) {
+ DataReader reader(data, size);
+ RtpFrameReferenceFinder reference_finder;
+
+ auto codec = static_cast<VideoCodecType>(reader.GetNum<uint8_t>() % 5);
+
+ while (reader.MoreToRead()) {
+ uint16_t first_seq_num = reader.GetNum<uint16_t>();
+ uint16_t last_seq_num = reader.GetNum<uint16_t>();
+ bool marker_bit = reader.GetNum<uint8_t>();
+
+ RTPVideoHeader video_header;
+ switch (reader.GetNum<uint8_t>() % 3) {
+ case 0:
+ video_header.frame_type = VideoFrameType::kEmptyFrame;
+ break;
+ case 1:
+ video_header.frame_type = VideoFrameType::kVideoFrameKey;
+ break;
+ case 2:
+ video_header.frame_type = VideoFrameType::kVideoFrameDelta;
+ break;
+ }
+
+ switch (codec) {
+ case kVideoCodecVP8:
+ reader.CopyTo(
+ &video_header.video_type_header.emplace<RTPVideoHeaderVP8>());
+ break;
+ case kVideoCodecVP9:
+ reader.CopyTo(
+ &video_header.video_type_header.emplace<RTPVideoHeaderVP9>());
+ break;
+ case kVideoCodecH264:
+ reader.CopyTo(
+ &video_header.video_type_header.emplace<RTPVideoHeaderH264>());
+ break;
+ default:
+ break;
+ }
+
+ video_header.generic = GenerateGenericFrameDependencies(&reader);
+
+ // clang-format off
+ auto frame = std::make_unique<RtpFrameObject>(
+ first_seq_num,
+ last_seq_num,
+ marker_bit,
+ /*times_nacked=*/0,
+ /*first_packet_received_time=*/0,
+ /*last_packet_received_time=*/0,
+ /*rtp_timestamp=*/0,
+ /*ntp_time_ms=*/0,
+ VideoSendTiming(),
+ /*payload_type=*/0,
+ codec,
+ kVideoRotation_0,
+ VideoContentType::UNSPECIFIED,
+ video_header,
+ /*color_space=*/absl::nullopt,
+ RtpPacketInfos(),
+ EncodedImageBuffer::Create(/*size=*/0));
+ // clang-format on
+
+ reference_finder.ManageFrame(std::move(frame));
+ }
+}
+
+} // namespace webrtc