/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <vector> #include <audio_utils/sndfile.h> #include <audio_utils/fifo.h> #include <fuzzer/FuzzedDataProvider.h> extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size){ if (data == nullptr || size < 6) { return 0; } FuzzedDataProvider provider(data, size); const bool throttleRead = provider.ConsumeBool(); const size_t frameSize = provider.ConsumeIntegralInRange<size_t>(1, 128); size_t maxNumberFrames = provider.remaining_bytes() / frameSize; if (maxNumberFrames >= ((uint32_t) INT32_MAX) / frameSize) { maxNumberFrames = (((uint32_t) INT32_MAX) / frameSize) - 1; } if (maxNumberFrames == 0) { // FrameSize is larger than bytes passed in return 0; } // Get buffer size size_t bufferMaxFrameCount = provider.ConsumeIntegralInRange<size_t>(1, maxNumberFrames); uint8_t* fifoBuffer = new uint8_t[bufferMaxFrameCount * frameSize]; // Audio_utils_fifo to be shared across reader/writer audio_utils_fifo fifo(bufferMaxFrameCount, frameSize, fifoBuffer, throttleRead); audio_utils_fifo_writer writer(fifo); audio_utils_fifo_reader reader(fifo); bool error = false; int32_t framesWritten = 0; while (provider.remaining_bytes() > 4) { //TODO use bufferMaxFrameCount? int32_t loopMaxWrite = bufferMaxFrameCount - framesWritten; int32_t framesToWrite = provider.ConsumeIntegralInRange<int32_t>(1, loopMaxWrite); size_t maxFramesLeft = provider.remaining_bytes() / frameSize; if (framesToWrite > maxFramesLeft) { framesToWrite = maxFramesLeft; } if (framesToWrite == 0) { // No more data to process after consuming Integral break; } std::vector<uint8_t> bytesToWrite = provider.ConsumeBytes<uint8_t>(framesToWrite * frameSize); ssize_t actualFramesWritten = writer.write(&bytesToWrite[0], framesToWrite); // Verify actualFramesWritten if (actualFramesWritten != framesToWrite) { error = true; break; } // Add count of frames just written to framesWritten framesWritten += actualFramesWritten; // Init framesToRead to read all framesWritten. // If another integral can be read from provider then update int32_t framesToRead = framesWritten; if (provider.remaining_bytes() >= 4) { framesToRead = provider.ConsumeIntegralInRange<size_t>(1, framesToRead); } uint8_t * readBuffer = new uint8_t[framesToRead * frameSize]; ssize_t actualFramesRead = reader.read(readBuffer, framesToRead); // Verify framesRead if (actualFramesRead != framesToRead) { error = true; break; } framesWritten -= framesToRead; delete[] readBuffer; readBuffer = NULL; } if (error) { abort(); } delete[] fifoBuffer; fifoBuffer = NULL; return 0; }