• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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