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 "audio_errors.h"
26 #include "hpae_sink_input_node.h"
27 #include "hpae_remote_output_cluster.h"
28 #include "hpae_mixer_node.h"
29 #include "audio_engine_log.h"
30 using namespace std;
31 using namespace OHOS::AudioStandard::HPAE;
32
33
34 namespace OHOS {
35 namespace AudioStandard {
36 using namespace std;
37 static const uint8_t *RAW_DATA = nullptr;
38 static size_t g_dataSize = 0;
39 static size_t g_pos;
40 const size_t THRESHOLD = 10;
41 const uint32_t DEFAULT_FRAME_LENGTH = 960;
42 const uint32_t DEFAULT_NODE_ID = 1243;
43 static vector<HpaeProcessorType> hpaeProcessorTypeMap = {
44 HPAE_SCENE_DEFAULT,
45 HPAE_SCENE_MUSIC,
46 HPAE_SCENE_GAME,
47 HPAE_SCENE_MOVIE,
48 HPAE_SCENE_SPEECH,
49 HPAE_SCENE_RING,
50 HPAE_SCENE_VOIP_DOWN,
51 HPAE_SCENE_OTHERS,
52 HPAE_SCENE_EFFECT_NONE,
53 HPAE_SCENE_EFFECT_OUT,
54 HPAE_SCENE_SPLIT_MEDIA,
55 HPAE_SCENE_SPLIT_NAVIGATION,
56 HPAE_SCENE_SPLIT_COMMUNICATION,
57 HPAE_SCENE_VOIP_UP,
58 HPAE_SCENE_RECORD,
59 HPAE_SCENE_PRE_ENHANCE,
60 HPAE_SCENE_ASR,
61 HPAE_SCENE_VOICE_MESSAGE,
62 HPAE_SCENE_COLLABORATIVE,
63 };
64
65 typedef void (*TestPtr)(const uint8_t *, size_t);
66
67 template<class T>
GetData()68 T GetData()
69 {
70 T object {};
71 size_t objectSize = sizeof(object);
72 if (RAW_DATA == nullptr || objectSize > g_dataSize - g_pos) {
73 return object;
74 }
75 errno_t ret = memcpy_s(&object, objectSize, RAW_DATA + g_pos, objectSize);
76 if (ret != EOK) {
77 return {};
78 }
79 g_pos += objectSize;
80 return object;
81 }
82
83 template<class T>
GetArrLength(T & arr)84 uint32_t GetArrLength(T& arr)
85 {
86 if (arr == nullptr) {
87 AUDIO_INFO_LOG("%{public}s: The array length is equal to 0", __func__);
88 return 0;
89 }
90 return sizeof(arr) / sizeof(arr[0]);
91 }
92
GetTestNodeInfo(HpaeNodeInfo & nodeInfo)93 static void GetTestNodeInfo(HpaeNodeInfo &nodeInfo)
94 {
95 nodeInfo.nodeId = DEFAULT_NODE_ID;
96 nodeInfo.frameLen = DEFAULT_FRAME_LENGTH;
97 nodeInfo.samplingRate = SAMPLE_RATE_48000;
98 nodeInfo.channels = STEREO;
99 nodeInfo.format = SAMPLE_S16LE;
100 nodeInfo.sceneType = HPAE_SCENE_RECORD;
101 nodeInfo.sourceBufferType = HPAE_SOURCE_BUFFER_TYPE_MIC;
102 }
103
DoProcessFuzzTest()104 void DoProcessFuzzTest()
105 {
106 HpaeSinkInfo sinkInfo;
107 HpaeNodeInfo nodeInfo;
108 GetTestNodeInfo(nodeInfo);
109 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
110 hpaeRemoteOutputCluster->DoProcess();
111 }
112
ResetFuzzTest()113 void ResetFuzzTest()
114 {
115 HpaeSinkInfo sinkInfo;
116 HpaeNodeInfo nodeInfo;
117 GetTestNodeInfo(nodeInfo);
118 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
119 hpaeRemoteOutputCluster->Reset();
120 }
121
ResetAllFuzzTest()122 void ResetAllFuzzTest()
123 {
124 HpaeSinkInfo sinkInfo;
125 HpaeNodeInfo nodeInfo;
126 GetTestNodeInfo(nodeInfo);
127 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
128 hpaeRemoteOutputCluster->ResetAll();
129 }
130
ConnectFuzzTest()131 void ConnectFuzzTest()
132 {
133 HpaeSinkInfo sinkInfo;
134 HpaeNodeInfo nodeInfo;
135 GetTestNodeInfo(nodeInfo);
136 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
137 std::shared_ptr<HpaeMixerNode> hpaeMixerNode = std::make_shared<HpaeMixerNode>(nodeInfo);
138 hpaeRemoteOutputCluster->Connect(hpaeMixerNode);
139 hpaeRemoteOutputCluster->DisConnect(hpaeMixerNode);
140 }
141
DisConnectFuzzTest()142 void DisConnectFuzzTest()
143 {
144 HpaeSinkInfo sinkInfo;
145 HpaeNodeInfo nodeInfo;
146 GetTestNodeInfo(nodeInfo);
147 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
148 std::shared_ptr<HpaeMixerNode> hpaeMixerNode = std::make_shared<HpaeMixerNode>(nodeInfo);
149 hpaeRemoteOutputCluster->DisConnect(hpaeMixerNode);
150 }
151
GetConverterNodeCountFuzzTest()152 void GetConverterNodeCountFuzzTest()
153 {
154 HpaeSinkInfo sinkInfo;
155 HpaeNodeInfo nodeInfo;
156 GetTestNodeInfo(nodeInfo);
157 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
158 hpaeRemoteOutputCluster->GetConverterNodeCount();
159 }
160
GetPreOutNumFuzzTest()161 void GetPreOutNumFuzzTest()
162 {
163 HpaeSinkInfo sinkInfo;
164 HpaeNodeInfo nodeInfo;
165 GetTestNodeInfo(nodeInfo);
166 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
167 hpaeRemoteOutputCluster->GetPreOutNum();
168 }
169
GetInstanceFuzzTest()170 void GetInstanceFuzzTest()
171 {
172 HpaeSinkInfo sinkInfo;
173 HpaeNodeInfo nodeInfo;
174 GetTestNodeInfo(nodeInfo);
175 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
176 std::string deviceClass = "123";
177 std::string deviceNetId = "456";
178 hpaeRemoteOutputCluster->GetInstance(deviceClass, deviceNetId);
179 }
180
InitFuzzTest()181 void InitFuzzTest()
182 {
183 HpaeSinkInfo sinkInfo;
184 HpaeNodeInfo nodeInfo;
185 GetTestNodeInfo(nodeInfo);
186 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
187 IAudioSinkAttr attr;
188 hpaeRemoteOutputCluster->Init(attr);
189 }
190
DeInitFuzzTest()191 void DeInitFuzzTest()
192 {
193 HpaeSinkInfo sinkInfo;
194 HpaeNodeInfo nodeInfo;
195 GetTestNodeInfo(nodeInfo);
196 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
197 hpaeRemoteOutputCluster->DeInit();
198 }
199
FlushFuzzTest()200 void FlushFuzzTest()
201 {
202 HpaeSinkInfo sinkInfo;
203 HpaeNodeInfo nodeInfo;
204 GetTestNodeInfo(nodeInfo);
205 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
206 hpaeRemoteOutputCluster->Flush();
207 }
208
PauseFuzzTest()209 void PauseFuzzTest()
210 {
211 HpaeSinkInfo sinkInfo;
212 HpaeNodeInfo nodeInfo;
213 GetTestNodeInfo(nodeInfo);
214 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
215 hpaeRemoteOutputCluster->Pause();
216 }
217
ResetRenderFuzzTest()218 void ResetRenderFuzzTest()
219 {
220 HpaeSinkInfo sinkInfo;
221 HpaeNodeInfo nodeInfo;
222 GetTestNodeInfo(nodeInfo);
223 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
224 hpaeRemoteOutputCluster->ResetRender();
225 }
226
ResumeFuzzTest()227 void ResumeFuzzTest()
228 {
229 HpaeSinkInfo sinkInfo;
230 HpaeNodeInfo nodeInfo;
231 GetTestNodeInfo(nodeInfo);
232 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
233 hpaeRemoteOutputCluster->Resume();
234 }
235
StartFuzzTest()236 void StartFuzzTest()
237 {
238 HpaeSinkInfo sinkInfo;
239 HpaeNodeInfo nodeInfo;
240 GetTestNodeInfo(nodeInfo);
241 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
242 hpaeRemoteOutputCluster->Start();
243 }
244
StopFuzzTest()245 void StopFuzzTest()
246 {
247 HpaeSinkInfo sinkInfo;
248 HpaeNodeInfo nodeInfo;
249 GetTestNodeInfo(nodeInfo);
250 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
251 hpaeRemoteOutputCluster->Stop();
252 }
253
SetTimeoutStopThdFuzzTest()254 void SetTimeoutStopThdFuzzTest()
255 {
256 HpaeSinkInfo sinkInfo;
257 HpaeNodeInfo nodeInfo;
258 GetTestNodeInfo(nodeInfo);
259 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
260 uint32_t timeoutThdMs = GetData<uint32_t>();
261 hpaeRemoteOutputCluster->SetTimeoutStopThd(timeoutThdMs);
262 }
263
GetFrameDataFuzzTest()264 void GetFrameDataFuzzTest()
265 {
266 HpaeSinkInfo sinkInfo;
267 HpaeNodeInfo nodeInfo;
268 GetTestNodeInfo(nodeInfo);
269 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
270 hpaeRemoteOutputCluster->GetFrameData();
271 }
272
GetStateFuzzTest()273 void GetStateFuzzTest()
274 {
275 HpaeSinkInfo sinkInfo;
276 HpaeNodeInfo nodeInfo;
277 GetTestNodeInfo(nodeInfo);
278 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
279 hpaeRemoteOutputCluster->GetState();
280 }
281
IsProcessClusterConnectedFuzzTest()282 void IsProcessClusterConnectedFuzzTest()
283 {
284 HpaeSinkInfo sinkInfo;
285 HpaeNodeInfo nodeInfo;
286 GetTestNodeInfo(nodeInfo);
287 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
288 uint32_t index = GetData<uint32_t>() % hpaeProcessorTypeMap.size();
289 HpaeProcessorType sceneType = hpaeProcessorTypeMap[index];
290 hpaeRemoteOutputCluster->IsProcessClusterConnected(sceneType);
291 }
292
UpdateAppsUidFuzzTest()293 void UpdateAppsUidFuzzTest()
294 {
295 HpaeSinkInfo sinkInfo;
296 HpaeNodeInfo nodeInfo;
297 GetTestNodeInfo(nodeInfo);
298 auto hpaeRemoteOutputCluster = std::make_shared<HpaeRemoteOutputCluster>(nodeInfo, sinkInfo);
299 std::vector<int32_t> appsUid = {GetData<int32_t>()};
300 hpaeRemoteOutputCluster->UpdateAppsUid(appsUid);
301 }
302
303 typedef void (*TestFuncs[21])();
304
305 TestFuncs g_testFuncs = {
306 DoProcessFuzzTest,
307 ResetFuzzTest,
308 ResetAllFuzzTest,
309 ConnectFuzzTest,
310 DisConnectFuzzTest,
311 GetConverterNodeCountFuzzTest,
312 GetPreOutNumFuzzTest,
313 GetInstanceFuzzTest,
314 InitFuzzTest,
315 DeInitFuzzTest,
316 FlushFuzzTest,
317 PauseFuzzTest,
318 ResetRenderFuzzTest,
319 ResumeFuzzTest,
320 StartFuzzTest,
321 StopFuzzTest,
322 SetTimeoutStopThdFuzzTest,
323 GetFrameDataFuzzTest,
324 GetStateFuzzTest,
325 IsProcessClusterConnectedFuzzTest,
326 UpdateAppsUidFuzzTest,
327 };
328
FuzzTest(const uint8_t * rawData,size_t size)329 bool FuzzTest(const uint8_t* rawData, size_t size)
330 {
331 if (rawData == nullptr) {
332 return false;
333 }
334
335 // initialize data
336 RAW_DATA = rawData;
337 g_dataSize = size;
338 g_pos = 0;
339
340 uint32_t code = GetData<uint32_t>();
341 uint32_t len = GetArrLength(g_testFuncs);
342 if (len > 0) {
343 g_testFuncs[code % len]();
344 } else {
345 AUDIO_INFO_LOG("%{public}s: The len length is equal to 0", __func__);
346 }
347
348 return true;
349 }
350
351 } // namespace AudioStandard
352 } // namesapce OHOS
353
354 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)355 extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size)
356 {
357 if (size < OHOS::AudioStandard::THRESHOLD) {
358 return 0;
359 }
360
361 OHOS::AudioStandard::FuzzTest(data, size);
362 return 0;
363 }
364