Improve neteq_rtp_fuzzer

This change lets the fuzzer modify the first few bytes of the RTP
payload. One of the benefits is that it can cover the RED header
splitter functionality.

The CL also fixes an issue found while running the fuzzer locally.

Bug: webrtc:11640
Change-Id: I7ca73676440897a14a0aaca796f70d381e016575
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/185819
Commit-Queue: Henrik Lundin <henrik.lundin@webrtc.org>
Reviewed-by: Sam Zackrisson <saza@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#32242}
diff --git a/modules/audio_coding/neteq/red_payload_splitter.cc b/modules/audio_coding/neteq/red_payload_splitter.cc
index 3e983dc..5681464 100644
--- a/modules/audio_coding/neteq/red_payload_splitter.cc
+++ b/modules/audio_coding/neteq/red_payload_splitter.cc
@@ -104,7 +104,9 @@
         payload_length -= kRedHeaderLength;
       }
       // Store in new list of packets.
-      new_headers.push_back(new_header);
+      if (new_header.payload_length > 0) {
+        new_headers.push_back(new_header);
+      }
     }
 
     if (new_headers.size() <= kMaxRedBlocks) {
diff --git a/test/fuzzers/neteq_rtp_fuzzer.cc b/test/fuzzers/neteq_rtp_fuzzer.cc
index d978199..348c84f 100644
--- a/test/fuzzers/neteq_rtp_fuzzer.cc
+++ b/test/fuzzers/neteq_rtp_fuzzer.cc
@@ -8,7 +8,9 @@
  *  be found in the AUTHORS file in the root of the source tree.
  */
 
+#include <algorithm>
 #include <cmath>
+#include <cstring>
 #include <memory>
 #include <vector>
 
@@ -64,6 +66,7 @@
                                       std::numeric_limits<int64_t>::max()));
     packet_ = input_->PopPacket();
     FuzzHeader();
+    MaybeFuzzPayload();
   }
 
   absl::optional<int64_t> NextPacketTime() const override {
@@ -79,6 +82,7 @@
     std::unique_ptr<PacketData> packet_to_return = std::move(packet_);
     packet_ = input_->PopPacket();
     FuzzHeader();
+    MaybeFuzzPayload();
     return packet_to_return;
   }
 
@@ -116,6 +120,30 @@
     RTC_CHECK_EQ(data_ix_ - start_ix, kNumBytesToFuzz);
   }
 
+  void MaybeFuzzPayload() {
+    // Read one byte of fuzz data to determine how many payload bytes to fuzz.
+    if (data_ix_ + 1 > data_.size()) {
+      ended_ = true;
+      return;
+    }
+    size_t bytes_to_fuzz = data_[data_ix_++];
+
+    // Restrict number of bytes to fuzz to 16; a reasonably low number enough to
+    // cover a few RED headers. Also don't write outside the payload length.
+    bytes_to_fuzz = std::min(bytes_to_fuzz % 16, packet_->payload.size());
+
+    if (bytes_to_fuzz == 0)
+      return;
+
+    if (data_ix_ + bytes_to_fuzz > data_.size()) {
+      ended_ = true;
+      return;
+    }
+
+    std::memcpy(packet_->payload.data(), &data_[data_ix_], bytes_to_fuzz);
+    data_ix_ += bytes_to_fuzz;
+  }
+
   bool ended_ = false;
   rtc::ArrayView<const uint8_t> data_;
   size_t data_ix_ = 0;