1 /*
2  * Copyright (C) 2021 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <vector>
18 #include <audio_utils/sndfile.h>
19 #include <audio_utils/fifo.h>
20 #include <fuzzer/FuzzedDataProvider.h>
21 
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)22 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size){
23     if (data == nullptr || size < 6) {
24         return 0;
25     }
26 
27     FuzzedDataProvider provider(data, size);
28 
29     const bool throttleRead = provider.ConsumeBool();
30     const size_t frameSize = provider.ConsumeIntegralInRange<size_t>(1, 128);
31 
32     size_t maxNumberFrames = provider.remaining_bytes() / frameSize;
33     if (maxNumberFrames >= ((uint32_t) INT32_MAX) / frameSize) {
34         maxNumberFrames = (((uint32_t) INT32_MAX) / frameSize) - 1;
35     }
36 
37     if (maxNumberFrames == 0) {
38         // FrameSize is larger than bytes passed in
39         return 0;
40     }
41 
42     // Get buffer size
43     size_t bufferMaxFrameCount = provider.ConsumeIntegralInRange<size_t>(1, maxNumberFrames);
44     uint8_t* fifoBuffer = new uint8_t[bufferMaxFrameCount * frameSize];
45 
46 
47     // Audio_utils_fifo to be shared across reader/writer
48     audio_utils_fifo fifo(bufferMaxFrameCount, frameSize, fifoBuffer, throttleRead);
49     audio_utils_fifo_writer writer(fifo);
50     audio_utils_fifo_reader reader(fifo);
51 
52     bool error = false;
53     int32_t framesWritten = 0;
54     while (provider.remaining_bytes() > 4) {
55 
56         //TODO use bufferMaxFrameCount?
57         int32_t loopMaxWrite = bufferMaxFrameCount - framesWritten;
58 
59         int32_t framesToWrite = provider.ConsumeIntegralInRange<int32_t>(1, loopMaxWrite);
60         size_t maxFramesLeft = provider.remaining_bytes() / frameSize;
61 
62         if (framesToWrite > maxFramesLeft) {
63             framesToWrite = maxFramesLeft;
64         }
65 
66         if (framesToWrite == 0) {
67             // No more data to process after consuming Integral
68             break;
69         }
70 
71         std::vector<uint8_t> bytesToWrite =
72             provider.ConsumeBytes<uint8_t>(framesToWrite * frameSize);
73         ssize_t actualFramesWritten = writer.write(&bytesToWrite[0], framesToWrite);
74 
75         // Verify actualFramesWritten
76         if (actualFramesWritten != framesToWrite) {
77             error = true;
78             break;
79         }
80 
81         // Add count of frames just written to framesWritten
82         framesWritten += actualFramesWritten;
83 
84         // Init framesToRead to read all framesWritten.
85         // If another integral can be read from provider then update
86         int32_t framesToRead = framesWritten;
87         if (provider.remaining_bytes() >= 4) {
88             framesToRead = provider.ConsumeIntegralInRange<size_t>(1, framesToRead);
89         }
90 
91         uint8_t * readBuffer = new uint8_t[framesToRead * frameSize];
92         ssize_t actualFramesRead = reader.read(readBuffer, framesToRead);
93 
94         // Verify framesRead
95         if (actualFramesRead != framesToRead) {
96             error = true;
97             break;
98         }
99 
100         framesWritten -= framesToRead;
101 
102         delete[] readBuffer;
103         readBuffer = NULL;
104     }
105 
106     if (error) {
107         abort();
108     }
109 
110     delete[] fifoBuffer;
111     fifoBuffer = NULL;
112 
113     return 0;
114 }