1 /*
2 * Copyright (c) 2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <iostream>
17 #include <cstddef>
18 #include <cstdint>
19 #include <vector>
20 #include <memory>
21 #include <queue>
22 #include <string>
23 #undef private
24 #include "hpae_msg_channel.h"
25 #include "hpae_node.h"
26 #include "hpae_pcm_buffer.h"
27 #include "audio_info.h"
28 #include "i_renderer_stream.h"
29 #include "linear_pos_time_model.h"
30 #include "hpae_sink_input_node.h"
31 #include "hpae_sink_output_node.h"
32 #include "audio_engine_log.h"
33 using namespace std;
34 using namespace OHOS::AudioStandard::HPAE;
35
36
37 namespace OHOS {
38 namespace AudioStandard {
39 using namespace std;
40 static const uint8_t *RAW_DATA = nullptr;
41 static size_t g_dataSize = 0;
42 static size_t g_pos;
43 const size_t THRESHOLD = 10;
44 typedef void (*TestPtr)(const uint8_t *, size_t);
45 static vector<HpaeSessionState> sessionStateMap = {
46 HPAE_SESSION_INVALID,
47 HPAE_SESSION_NEW,
48 HPAE_SESSION_PREPARED,
49 HPAE_SESSION_RUNNING,
50 HPAE_SESSION_PAUSING,
51 HPAE_SESSION_PAUSED,
52 HPAE_SESSION_STOPPING,
53 HPAE_SESSION_STOPPED,
54 HPAE_SESSION_RELEASED,
55 };
56 template<class T>
GetData()57 T GetData()
58 {
59 T object {};
60 size_t objectSize = sizeof(object);
61 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
62 return object;
63 }
64 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
65 if (ret != EOK) {
66 return {};
67 }
68 g_pos += objectSize;
69 return object;
70 }
71
72 template<class T>
GetArrLength(T & arr)73 uint32_t GetArrLength(T& arr)
74 {
75 if (arr == nullptr) {
76 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
77 return 0;
78 }
79 return sizeof(arr) / sizeof(arr[0]);
80 }
81
82
DoProcessFuzzTest()83 void DoProcessFuzzTest()
84 {
85 HpaeNodeInfo nodeInfo;
86 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
87 hpaeSinkInputNode->DoProcess();
88 }
89
ResetFuzzTest()90 void ResetFuzzTest()
91 {
92 HpaeNodeInfo nodeInfo;
93 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
94 hpaeSinkInputNode->Reset();
95 }
96
ResetAllFuzzTest()97 void ResetAllFuzzTest()
98 {
99 HpaeNodeInfo nodeInfo;
100 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
101 hpaeSinkInputNode->ResetAll();
102 }
103
RegisterWriteCallbackFuzzTest()104 void RegisterWriteCallbackFuzzTest()
105 {
106 HpaeNodeInfo nodeInfo;
107 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
108 const std::weak_ptr<IStreamCallback> &callback = std::weak_ptr<IStreamCallback>();
109 hpaeSinkInputNode->RegisterWriteCallback(callback);
110 }
111
FlushFuzzTest()112 void FlushFuzzTest()
113 {
114 HpaeNodeInfo nodeInfo;
115 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
116 hpaeSinkInputNode->Flush();
117 }
118
DrainFuzzTest()119 void DrainFuzzTest()
120 {
121 HpaeNodeInfo nodeInfo;
122 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
123 hpaeSinkInputNode->Drain();
124 }
125
SetStateFuzzTest()126 void SetStateFuzzTest()
127 {
128 HpaeNodeInfo nodeInfo;
129 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
130 uint32_t index = GetData<uint32_t>() % sessionStateMap.size();
131 HpaeSessionState renderState = sessionStateMap[index];
132 hpaeSinkInputNode->SetState(renderState);
133 }
134
GetStateFuzzTest()135 void GetStateFuzzTest()
136 {
137 HpaeNodeInfo nodeInfo;
138 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
139 hpaeSinkInputNode->GetState();
140 }
141
GetFramesWrittenFuzzTest()142 void GetFramesWrittenFuzzTest()
143 {
144 HpaeNodeInfo nodeInfo;
145 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
146 hpaeSinkInputNode->GetFramesWritten();
147 }
148
GetCurrentPositionFuzzTest()149 void GetCurrentPositionFuzzTest()
150 {
151 HpaeNodeInfo nodeInfo;
152 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
153 uint64_t framePosition = GetData<uint64_t>();
154 std::vector<uint64_t> timestamp;
155 hpaeSinkInputNode->GetCurrentPosition(framePosition, timestamp);
156 }
157
RewindHistoryBufferFuzzTest()158 void RewindHistoryBufferFuzzTest()
159 {
160 HpaeNodeInfo nodeInfo;
161 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
162 uint64_t rewindTime = GetData<uint64_t>();
163 hpaeSinkInputNode->RewindHistoryBuffer(rewindTime);
164 }
165
SetAppUidFuzzTest()166 void SetAppUidFuzzTest()
167 {
168 HpaeNodeInfo nodeInfo;
169 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
170 int32_t appUid = GetData<int32_t>();
171 hpaeSinkInputNode->SetAppUid(appUid);
172 }
173
GetAppUidFuzzTest()174 void GetAppUidFuzzTest()
175 {
176 HpaeNodeInfo nodeInfo;
177 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
178 hpaeSinkInputNode->GetAppUid();
179 }
180
SetOffloadEnabledFuzzTest()181 void SetOffloadEnabledFuzzTest()
182 {
183 HpaeNodeInfo nodeInfo;
184 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
185 hpaeSinkInputNode->SetOffloadEnabled(true);
186 }
187
GetOffloadEnabledFuzzTest()188 void GetOffloadEnabledFuzzTest()
189 {
190 HpaeNodeInfo nodeInfo;
191 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
192 hpaeSinkInputNode->GetOffloadEnabled();
193 }
194
SetLoudnessGainFuzzTest()195 void SetLoudnessGainFuzzTest()
196 {
197 HpaeNodeInfo nodeInfo;
198 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
199 float loudnessGain = GetData<float>();
200 hpaeSinkInputNode->SetLoudnessGain(loudnessGain);
201 }
202
GetLoudnessGainFuzzTest()203 void GetLoudnessGainFuzzTest()
204 {
205 HpaeNodeInfo nodeInfo;
206 auto hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
207 hpaeSinkInputNode->GetLoudnessGain();
208 }
209
210 typedef void (*TestFuncs[17])();
211
212 TestFuncs g_testFuncs = {
213 DoProcessFuzzTest,
214 ResetFuzzTest,
215 ResetAllFuzzTest,
216 RegisterWriteCallbackFuzzTest,
217 FlushFuzzTest,
218 DrainFuzzTest,
219 SetStateFuzzTest,
220 GetStateFuzzTest,
221 GetFramesWrittenFuzzTest,
222 GetCurrentPositionFuzzTest,
223 RewindHistoryBufferFuzzTest,
224 SetAppUidFuzzTest,
225 GetAppUidFuzzTest,
226 SetOffloadEnabledFuzzTest,
227 GetOffloadEnabledFuzzTest,
228 SetLoudnessGainFuzzTest,
229 GetLoudnessGainFuzzTest,
230 };
231
FuzzTest(const uint8_t * rawData,size_t size)232 bool FuzzTest(const uint8_t* rawData, size_t size)
233 {
234 if (rawData == nullptr) {
235 return false;
236 }
237
238 // initialize data
239 RAW_DATA = rawData;
240 g_dataSize = size;
241 g_pos = 0;
242
243 uint32_t code = GetData<uint32_t>();
244 uint32_t len = GetArrLength(g_testFuncs);
245 if (len > 0) {
246 g_testFuncs[code % len]();
247 } else {
248 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
249 }
250
251 return true;
252 }
253
254 } // namespace AudioStandard
255 } // namesapce OHOS
256
257 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)258 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
259 {
260 if (size < OHOS::AudioStandard::THRESHOLD) {
261 return 0;
262 }
263
264 OHOS::AudioStandard::FuzzTest(data, size);
265 return 0;
266 }
267