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_process_cluster.h"
25 #include "hpae_sink_input_node.h"
26 #include "hpae_sink_output_node.h"
27 #include "audio_effect.h"
28 #include "audio_engine_log.h"
29 using namespace std;
30 using namespace OHOS::AudioStandard::HPAE;
31
32
33 namespace OHOS {
34 namespace AudioStandard {
35 using namespace std;
36 static const uint8_t *RAW_DATA = nullptr;
37 static size_t g_dataSize = 0;
38 static size_t g_pos;
39 const size_t THRESHOLD = 10;
40 const uint32_t DEFAULT_FRAME_LENGTH = 960;
41 const uint32_t DEFAULT_NODE_ID = 1243;
42 typedef void (*TestPtr)(const uint8_t *, size_t);
43
44 template<class T>
GetData()45 T GetData()
46 {
47 T object {};
48 size_t objectSize = sizeof(object);
49 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
50 return object;
51 }
52 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
53 if (ret != EOK) {
54 return {};
55 }
56 g_pos += objectSize;
57 return object;
58 }
59
60 template<class T>
GetArrLength(T & arr)61 uint32_t GetArrLength(T& arr)
62 {
63 if (arr == nullptr) {
64 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
65 return 0;
66 }
67 return sizeof(arr) / sizeof(arr[0]);
68 }
69
GetTestNodeInfo(HpaeNodeInfo & nodeInfo)70 static void GetTestNodeInfo(HpaeNodeInfo &nodeInfo)
71 {
72 nodeInfo.nodeId = DEFAULT_NODE_ID;
73 nodeInfo.frameLen = DEFAULT_FRAME_LENGTH;
74 nodeInfo.samplingRate = SAMPLE_RATE_48000;
75 nodeInfo.channels = STEREO;
76 nodeInfo.format = SAMPLE_S16LE;
77 nodeInfo.sceneType = HPAE_SCENE_MUSIC;
78 nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC;
79 }
80
CreateHpaeInfo(HpaeNodeInfo & nodeInfo,HpaeSinkInfo & dummySinkInfo)81 static void CreateHpaeInfo(HpaeNodeInfo &nodeInfo, HpaeSinkInfo &dummySinkInfo)
82 {
83 GetTestNodeInfo(nodeInfo);
84 dummySinkInfo.channels = STEREO;
85 dummySinkInfo.frameLen = DEFAULT_FRAME_LENGTH;
86 dummySinkInfo.format = SAMPLE_F32LE;
87 dummySinkInfo.samplingRate = SAMPLE_RATE_48000;
88 }
89
DoProcessFuzzTest()90 void DoProcessFuzzTest()
91 {
92 HpaeNodeInfo nodeInfo;
93 HpaeSinkInfo dummySinkInfo;
94 CreateHpaeInfo(nodeInfo, dummySinkInfo);
95 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
96 hpaeProcessCluster->DoProcess();
97 }
98
ResetFuzzTest()99 void ResetFuzzTest()
100 {
101 HpaeNodeInfo nodeInfo;
102 HpaeSinkInfo dummySinkInfo;
103 CreateHpaeInfo(nodeInfo, dummySinkInfo);
104 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
105 hpaeProcessCluster->Reset();
106 }
107
ResetAllFuzzTest()108 void ResetAllFuzzTest()
109 {
110 HpaeNodeInfo nodeInfo;
111 HpaeSinkInfo dummySinkInfo;
112 CreateHpaeInfo(nodeInfo, dummySinkInfo);
113 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
114 hpaeProcessCluster->ResetAll();
115 }
116
GetSharedInstanceFuzzTest()117 void GetSharedInstanceFuzzTest()
118 {
119 HpaeNodeInfo nodeInfo;
120 HpaeSinkInfo dummySinkInfo;
121 CreateHpaeInfo(nodeInfo, dummySinkInfo);
122 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
123 hpaeProcessCluster->GetSharedInstance();
124 }
125
GetOutputPortFuzzTest()126 void GetOutputPortFuzzTest()
127 {
128 HpaeNodeInfo nodeInfo;
129 HpaeSinkInfo dummySinkInfo;
130 CreateHpaeInfo(nodeInfo, dummySinkInfo);
131 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
132 hpaeProcessCluster->GetOutputPort();
133 }
134
ConnectFuzzTest()135 void ConnectFuzzTest()
136 {
137 HpaeNodeInfo nodeInfo;
138 HpaeSinkInfo dummySinkInfo;
139 CreateHpaeInfo(nodeInfo, dummySinkInfo);
140 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
141 std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
142 hpaeProcessCluster->Connect(hpaeSinkInputNode);
143 hpaeProcessCluster->DisConnect(hpaeSinkInputNode);
144 }
145
DisConnectFuzzTest()146 void DisConnectFuzzTest()
147 {
148 HpaeNodeInfo nodeInfo;
149 HpaeSinkInfo dummySinkInfo;
150 CreateHpaeInfo(nodeInfo, dummySinkInfo);
151 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
152 std::shared_ptr<HpaeSinkInputNode> hpaeSinkInputNode = std::make_shared<HpaeSinkInputNode>(nodeInfo);
153 hpaeProcessCluster->DisConnect(hpaeSinkInputNode);
154 }
155
GetGainNodeCountFuzzTest()156 void GetGainNodeCountFuzzTest()
157 {
158 HpaeNodeInfo nodeInfo;
159 HpaeSinkInfo dummySinkInfo;
160 CreateHpaeInfo(nodeInfo, dummySinkInfo);
161 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
162 hpaeProcessCluster->GetGainNodeCount();
163 }
164
GetConverterNodeCountFuzzTest()165 void GetConverterNodeCountFuzzTest()
166 {
167 HpaeNodeInfo nodeInfo;
168 HpaeSinkInfo dummySinkInfo;
169 CreateHpaeInfo(nodeInfo, dummySinkInfo);
170 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
171 hpaeProcessCluster->GetConverterNodeCount();
172 }
173
GetPreOutNumFuzzTest()174 void GetPreOutNumFuzzTest()
175 {
176 HpaeNodeInfo nodeInfo;
177 HpaeSinkInfo dummySinkInfo;
178 CreateHpaeInfo(nodeInfo, dummySinkInfo);
179 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
180 hpaeProcessCluster->GetPreOutNum();
181 }
182
AudioRendererCreateFuzzTest()183 void AudioRendererCreateFuzzTest()
184 {
185 HpaeNodeInfo nodeInfo;
186 HpaeSinkInfo dummySinkInfo;
187 CreateHpaeInfo(nodeInfo, dummySinkInfo);
188 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
189 hpaeProcessCluster->AudioRendererCreate(nodeInfo);
190 }
191
AudioRendererStartFuzzTest()192 void AudioRendererStartFuzzTest()
193 {
194 HpaeNodeInfo nodeInfo;
195 HpaeSinkInfo dummySinkInfo;
196 CreateHpaeInfo(nodeInfo, dummySinkInfo);
197 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
198 hpaeProcessCluster->AudioRendererStart(nodeInfo);
199 }
200
AudioRendererStopFuzzTest()201 void AudioRendererStopFuzzTest()
202 {
203 HpaeNodeInfo nodeInfo;
204 HpaeSinkInfo dummySinkInfo;
205 CreateHpaeInfo(nodeInfo, dummySinkInfo);
206 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
207 hpaeProcessCluster->AudioRendererStop(nodeInfo);
208 }
209
AudioRendererReleaseFuzzTest()210 void AudioRendererReleaseFuzzTest()
211 {
212 HpaeNodeInfo nodeInfo;
213 HpaeSinkInfo dummySinkInfo;
214 CreateHpaeInfo(nodeInfo, dummySinkInfo);
215 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
216 hpaeProcessCluster->AudioRendererRelease(nodeInfo);
217 }
218
GetNodeInputFormatInfoFuzzTest()219 void GetNodeInputFormatInfoFuzzTest()
220 {
221 HpaeNodeInfo nodeInfo;
222 HpaeSinkInfo dummySinkInfo;
223 CreateHpaeInfo(nodeInfo, dummySinkInfo);
224 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
225 uint32_t sessionId = GetData<uint32_t>();
226 AudioBasicFormat basicFormat;
227 hpaeProcessCluster->GetNodeInputFormatInfo(sessionId, basicFormat);
228 }
229
GetGainNodeByIdFuzzTest()230 void GetGainNodeByIdFuzzTest()
231 {
232 HpaeNodeInfo nodeInfo;
233 HpaeSinkInfo dummySinkInfo;
234 CreateHpaeInfo(nodeInfo, dummySinkInfo);
235 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
236 uint32_t id = GetData<uint32_t>();
237 hpaeProcessCluster->GetGainNodeById(id);
238 }
239
GetConverterNodeByIdFuzzTest()240 void GetConverterNodeByIdFuzzTest()
241 {
242 HpaeNodeInfo nodeInfo;
243 HpaeSinkInfo dummySinkInfo;
244 CreateHpaeInfo(nodeInfo, dummySinkInfo);
245 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
246 uint32_t id = GetData<uint32_t>();
247 hpaeProcessCluster->GetConverterNodeById(id);
248 }
249
SetConnectedFlagFuzzTest()250 void SetConnectedFlagFuzzTest()
251 {
252 HpaeNodeInfo nodeInfo;
253 HpaeSinkInfo dummySinkInfo;
254 CreateHpaeInfo(nodeInfo, dummySinkInfo);
255 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
256 hpaeProcessCluster->SetConnectedFlag(true);
257 }
258
GetConnectedFlagFuzzTest()259 void GetConnectedFlagFuzzTest()
260 {
261 HpaeNodeInfo nodeInfo;
262 HpaeSinkInfo dummySinkInfo;
263 CreateHpaeInfo(nodeInfo, dummySinkInfo);
264 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
265 hpaeProcessCluster->GetConnectedFlag();
266 }
267
SetupAudioLimiterFuzzTest()268 void SetupAudioLimiterFuzzTest()
269 {
270 HpaeNodeInfo nodeInfo;
271 HpaeSinkInfo dummySinkInfo;
272 CreateHpaeInfo(nodeInfo, dummySinkInfo);
273 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
274 hpaeProcessCluster->SetupAudioLimiter();
275 }
276
SetLoudnessGainFuzzTest()277 void SetLoudnessGainFuzzTest()
278 {
279 HpaeNodeInfo nodeInfo;
280 HpaeSinkInfo dummySinkInfo;
281 CreateHpaeInfo(nodeInfo, dummySinkInfo);
282 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
283 uint32_t sessionId = GetData<uint32_t>();
284 float loudnessGain = GetData<float>();
285 hpaeProcessCluster->SetLoudnessGain(sessionId, loudnessGain);
286 }
287
DisConnectMixerNodeFuzzTest()288 void DisConnectMixerNodeFuzzTest()
289 {
290 HpaeNodeInfo nodeInfo;
291 HpaeSinkInfo dummySinkInfo;
292 CreateHpaeInfo(nodeInfo, dummySinkInfo);
293 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
294 hpaeProcessCluster->DisConnectMixerNode();
295 }
296
InitEffectBufferFuzzTest()297 void InitEffectBufferFuzzTest()
298 {
299 HpaeNodeInfo nodeInfo;
300 HpaeSinkInfo dummySinkInfo;
301 CreateHpaeInfo(nodeInfo, dummySinkInfo);
302 auto hpaeProcessCluster = std::make_shared<HpaeProcessCluster>(nodeInfo, dummySinkInfo);
303 uint32_t sessionId = GetData<uint32_t>();
304 hpaeProcessCluster->InitEffectBuffer(sessionId);
305 }
306
307 typedef void (*TestFuncs[23])();
308
309 TestFuncs g_testFuncs = {
310 DoProcessFuzzTest,
311 ResetFuzzTest,
312 ResetAllFuzzTest,
313 GetSharedInstanceFuzzTest,
314 GetOutputPortFuzzTest,
315 ConnectFuzzTest,
316 DisConnectFuzzTest,
317 GetGainNodeCountFuzzTest,
318 GetConverterNodeCountFuzzTest,
319 GetPreOutNumFuzzTest,
320 AudioRendererCreateFuzzTest,
321 AudioRendererStartFuzzTest,
322 AudioRendererStopFuzzTest,
323 AudioRendererReleaseFuzzTest,
324 GetNodeInputFormatInfoFuzzTest,
325 GetGainNodeByIdFuzzTest,
326 GetConverterNodeByIdFuzzTest,
327 SetConnectedFlagFuzzTest,
328 GetConnectedFlagFuzzTest,
329 SetupAudioLimiterFuzzTest,
330 SetLoudnessGainFuzzTest,
331 DisConnectMixerNodeFuzzTest,
332 InitEffectBufferFuzzTest,
333 };
334
FuzzTest(const uint8_t * rawData,size_t size)335 bool FuzzTest(const uint8_t* rawData, size_t size)
336 {
337 if (rawData == nullptr) {
338 return false;
339 }
340
341 // initialize data
342 RAW_DATA = rawData;
343 g_dataSize = size;
344 g_pos = 0;
345
346 uint32_t code = GetData<uint32_t>();
347 uint32_t len = GetArrLength(g_testFuncs);
348 if (len > 0) {
349 g_testFuncs[code % len]();
350 } else {
351 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
352 }
353
354 return true;
355 }
356
357 } // namespace AudioStandard
358 } // namesapce OHOS
359
360 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)361 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
362 {
363 if (size < OHOS::AudioStandard::THRESHOLD) {
364 return 0;
365 }
366
367 OHOS::AudioStandard::FuzzTest(data, size);
368 return 0;
369 }
370