diff options
Diffstat (limited to '')
-rw-r--r-- | third_party/libwebrtc/test/fuzzers/audio_decoder_fuzzer.cc | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/third_party/libwebrtc/test/fuzzers/audio_decoder_fuzzer.cc b/third_party/libwebrtc/test/fuzzers/audio_decoder_fuzzer.cc new file mode 100644 index 0000000000..1db332eeb5 --- /dev/null +++ b/third_party/libwebrtc/test/fuzzers/audio_decoder_fuzzer.cc @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2015 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 "test/fuzzers/audio_decoder_fuzzer.h" + +#include <limits> + +#include "absl/types/optional.h" +#include "api/audio_codecs/audio_decoder.h" +#include "modules/rtp_rtcp/source/byte_io.h" +#include "rtc_base/checks.h" + +namespace webrtc { +namespace { +template <typename T, unsigned int B = sizeof(T)> +bool ParseInt(const uint8_t** data, size_t* remaining_size, T* value) { + static_assert(std::numeric_limits<T>::is_integer, "Type must be an integer."); + static_assert(sizeof(T) <= sizeof(uint64_t), + "Cannot read wider than uint64_t."); + static_assert(B <= sizeof(T), "T must be at least B bytes wide."); + if (B > *remaining_size) + return false; + uint64_t val = ByteReader<uint64_t, B>::ReadBigEndian(*data); + *data += B; + *remaining_size -= B; + *value = static_cast<T>(val); + return true; +} +} // namespace + +// This function reads two bytes from the beginning of `data`, interprets them +// as the first packet length, and reads this many bytes if available. The +// payload is inserted into the decoder, and the process continues until no more +// data is available. Either AudioDecoder::Decode or +// AudioDecoder::DecodeRedundant is used, depending on the value of +// `decode_type`. +void FuzzAudioDecoder(DecoderFunctionType decode_type, + const uint8_t* data, + size_t size, + AudioDecoder* decoder, + int sample_rate_hz, + size_t max_decoded_bytes, + int16_t* decoded) { + const uint8_t* data_ptr = data; + size_t remaining_size = size; + size_t packet_len; + constexpr size_t kMaxNumFuzzedPackets = 200; + for (size_t num_packets = 0; num_packets < kMaxNumFuzzedPackets; + ++num_packets) { + if (!(ParseInt<size_t, 2>(&data_ptr, &remaining_size, &packet_len) && + packet_len <= remaining_size)) { + break; + } + AudioDecoder::SpeechType speech_type; + switch (decode_type) { + case DecoderFunctionType::kNormalDecode: + decoder->Decode(data_ptr, packet_len, sample_rate_hz, max_decoded_bytes, + decoded, &speech_type); + break; + case DecoderFunctionType::kRedundantDecode: + decoder->DecodeRedundant(data_ptr, packet_len, sample_rate_hz, + max_decoded_bytes, decoded, &speech_type); + break; + } + data_ptr += packet_len; + remaining_size -= packet_len; + } +} + +} // namespace webrtc |