diff --git a/webrtc/test/fuzzers/rtp_header_fuzzer.cc b/webrtc/test/fuzzers/rtp_header_fuzzer.cc index fcc737728c..914a8fb949 100644 --- a/webrtc/test/fuzzers/rtp_header_fuzzer.cc +++ b/webrtc/test/fuzzers/rtp_header_fuzzer.cc @@ -10,29 +10,35 @@ #include -#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" #include "webrtc/modules/rtp_rtcp/include/rtp_rtcp_defines.h" +#include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" namespace webrtc { +// We decide which header extensions to register by reading one byte +// from the beginning of |data| and interpreting it as a bitmask over +// the RTPExtensionType enum. This assert ensures one byte is enough. +static_assert(kRtpExtensionNumberOfExtensions <= 8, + "Insufficient bits read to configure all header extensions. Add " + "an extra byte and update the switches."); + void FuzzOneInput(const uint8_t* data, size_t size) { if (size <= 1) return; - // We decide which header extensions to register by reading one byte - // from the beginning of |data| and interpreting it as a bitmask - // over the RTPExtensionType enum. That byte shouldn't also be part - // of the packet, so we adjust |data| and |size| to remove it. + // Don't use the configuration byte as part of the packet. std::bitset<8> extensionMask(data[0]); data++; size--; RtpPacketReceived::ExtensionManager extensions; - for (int i = 1; i <= kRtpExtensionNumberOfExtensions; i++) { - // Skip i=0 which is kRtpExtensionNone i.e. not an actual extension. - if (extensionMask[i]) { - // We use i as the ID; it's used in negotiation so not relevant. - extensions.Register(static_cast(i), i); + for (int i = 0; i < kRtpExtensionNumberOfExtensions; i++) { + RTPExtensionType extension_type = static_cast(i); + if (extensionMask[i] && extension_type != kRtpExtensionNone) { + // Extensions are registered with an ID, which you signal to the + // peer so they know what to expect. This code only cares about + // parsing so the value of the ID isn't relevant; we use i. + extensions.Register(extension_type, i); } } diff --git a/webrtc/test/fuzzers/rtp_packet_fuzzer.cc b/webrtc/test/fuzzers/rtp_packet_fuzzer.cc index a9efdb96ec..2a67a8bea7 100644 --- a/webrtc/test/fuzzers/rtp_packet_fuzzer.cc +++ b/webrtc/test/fuzzers/rtp_packet_fuzzer.cc @@ -7,13 +7,41 @@ * 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/rtp_rtcp/source/rtp_header_extension.h" +#include "webrtc/modules/rtp_rtcp/source/rtp_header_extensions.h" #include "webrtc/modules/rtp_rtcp/source/rtp_packet_received.h" namespace webrtc { -void FuzzOneInput(const uint8_t* data, size_t size) { - RtpPacketReceived packet; +// We decide which header extensions to register by reading one byte +// from the beginning of |data| and interpreting it as a bitmask over +// the RTPExtensionType enum. This assert ensures one byte is enough. +static_assert(kRtpExtensionNumberOfExtensions <= 8, + "Insufficient bits read to configure all header extensions. Add " + "an extra byte and update the switches."); +void FuzzOneInput(const uint8_t* data, size_t size) { + if (size <= 1) + return; + + // Don't use the configuration byte as part of the packet. + std::bitset<8> extensionMask(data[0]); + data++; + size--; + + RtpPacketReceived::ExtensionManager extensions; + for (int i = 0; i < kRtpExtensionNumberOfExtensions; i++) { + RTPExtensionType extension_type = static_cast(i); + if (extensionMask[i] && extension_type != kRtpExtensionNone) { + // Extensions are registered with an ID, which you signal to the + // peer so they know what to expect. This code only cares about + // parsing so the value of the ID isn't relevant; we use i. + extensions.Register(extension_type, i); + } + } + + RtpPacketReceived packet(&extensions); packet.Parse(data, size); // Call packet accessors because they have extra checks. @@ -23,7 +51,40 @@ void FuzzOneInput(const uint8_t* data, size_t size) { packet.Timestamp(); packet.Ssrc(); packet.Csrcs(); + + // Each extension has its own getter. It is supported behaviour to + // call GetExtension on an extension which was not registered, so we + // don't check the bitmask here. + for (int i = 0; i < kRtpExtensionNumberOfExtensions; i++) { + switch (static_cast(i)) { + case kRtpExtensionNone: + case kRtpExtensionNumberOfExtensions: + break; + case kRtpExtensionTransmissionTimeOffset: + int32_t offset; + packet.GetExtension(&offset); + break; + case kRtpExtensionAudioLevel: + bool voice_activity; + uint8_t audio_level; + packet.GetExtension(&voice_activity, &audio_level); + break; + case kRtpExtensionAbsoluteSendTime: + uint32_t sendtime; + packet.GetExtension(&sendtime); + break; + case kRtpExtensionVideoRotation: + uint8_t rotation; + packet.GetExtension(&rotation); + break; + case kRtpExtensionTransportSequenceNumber: + uint16_t seqnum; + packet.GetExtension(&seqnum); + break; + case kRtpExtensionPlayoutDelay: + // TODO(katrielc) Add this once it's written. + break; + } + } } - } // namespace webrtc -