summaryrefslogtreecommitdiff
path: root/fuzzer/libldac_encode_fuzzer.cc
diff options
context:
space:
mode:
Diffstat (limited to 'fuzzer/libldac_encode_fuzzer.cc')
-rw-r--r--fuzzer/libldac_encode_fuzzer.cc110
1 files changed, 110 insertions, 0 deletions
diff --git a/fuzzer/libldac_encode_fuzzer.cc b/fuzzer/libldac_encode_fuzzer.cc
new file mode 100644
index 0000000..501d177
--- /dev/null
+++ b/fuzzer/libldac_encode_fuzzer.cc
@@ -0,0 +1,110 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <stdint.h>
+#include <stddef.h>
+#include "ldacBT.h"
+
+#include <fuzzer/FuzzedDataProvider.h>
+#include <vector>
+
+constexpr LDACBT_SMPL_FMT_T kFormat[] = {
+ LDACBT_SMPL_FMT_S16, LDACBT_SMPL_FMT_S24, LDACBT_SMPL_FMT_S32,
+ LDACBT_SMPL_FMT_F32};
+constexpr int32_t kEqmidValue[] = {LDACBT_EQMID_HQ, LDACBT_EQMID_SQ,
+ LDACBT_EQMID_MQ};
+constexpr int32_t kChannel[] = {LDACBT_CHANNEL_MODE_STEREO,
+ LDACBT_CHANNEL_MODE_DUAL_CHANNEL,
+ LDACBT_CHANNEL_MODE_MONO};
+constexpr int32_t kSamplingFrequency[] = {44100, 48000, 2 * 44100, 2 * 48000};
+constexpr int32_t kLdacBtRequiredMtu = 679;
+constexpr int32_t kMaxWlValue = 4;
+constexpr int32_t kMinChValue = 1;
+constexpr int32_t kMaxChValue = 2;
+constexpr int32_t kOutputSize = 1024;
+
+class Codec {
+public:
+ Codec(const uint8_t *data, size_t size) : mFdp(data, size){};
+ ~Codec() { deInitEncoder(); }
+ bool initEncoder();
+ void deInitEncoder();
+ void encodeFrames(const uint8_t *data, size_t size);
+ void getSamplingFrequeny();
+ void getBitrate();
+ void getVersion();
+ FuzzedDataProvider mFdp;
+
+private:
+ int32_t mChannel;
+ LDACBT_SMPL_FMT_T mFormat;
+ HANDLE_LDAC_BT mHandleLdacBt;
+};
+
+bool Codec::initEncoder() {
+ mHandleLdacBt = ldacBT_get_handle();
+
+ mChannel = mFdp.PickValueInArray(kChannel);
+ mFormat = mFdp.PickValueInArray(kFormat);
+ int32_t status = ldacBT_init_handle_encode(
+ mHandleLdacBt, kLdacBtRequiredMtu, mFdp.PickValueInArray(kEqmidValue),
+ mChannel, mFormat, mFdp.PickValueInArray(kSamplingFrequency));
+ if (!status) {
+ return true;
+ }
+ return false;
+}
+
+void Codec::encodeFrames(const uint8_t *data, size_t size) {
+ int32_t pcmUsed, streamSize, frameNum;
+ unsigned char pStream[kOutputSize];
+ int32_t ch, wl, frameSize;
+ ch = (mChannel == LDAC_CCI_MONO) ? kMinChValue : kMaxChValue;
+ wl = mFormat > kMaxWlValue ? kMaxWlValue : mFormat;
+ frameSize = LDACBT_ENC_LSU * ch * wl;
+ std::vector<uint8_t> tmpData(frameSize);
+ uint8_t *readPointer = const_cast<uint8_t *>(data);
+ while (size > 0) {
+ if (size < frameSize) {
+ memcpy(tmpData.data(), data, size);
+ size = frameSize;
+ readPointer = tmpData.data();
+ }
+ ldacBT_encode(mHandleLdacBt, readPointer, &pcmUsed, pStream, &streamSize,
+ &frameNum);
+ readPointer += frameSize;
+ size -= frameSize;
+ }
+}
+
+void Codec::getSamplingFrequeny() { ldacBT_get_sampling_freq(mHandleLdacBt); }
+
+void Codec::getBitrate() { ldacBT_get_bitrate(mHandleLdacBt); }
+
+void Codec::getVersion() { ldacBT_get_version(); }
+
+void Codec::deInitEncoder() {
+ ldacBT_close_handle(mHandleLdacBt);
+ ldacBT_free_handle(mHandleLdacBt);
+}
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t size) {
+ Codec codec(buf, size);
+ /* initEncoder() initializes mHandleLdacBt and is supposed to be called before
+ encoding begins. Hence initEncoder() is not included in the lambda
+ construct. */
+ if (codec.initEncoder()) {
+ while (codec.mFdp.remaining_bytes() > 0) {
+ auto executeFunction =
+ codec.mFdp.PickValueInArray<const std::function<void()>>({
+ [&]() { codec.encodeFrames(buf, size); },
+ [&]() { codec.getSamplingFrequeny(); },
+ [&]() { codec.getBitrate(); },
+ [&]() { codec.getVersion(); },
+ });
+ executeFunction();
+ }
+ }
+ return 0;
+}