1 /*
2  * Copyright (c) 2023 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 "medialibraryextension_fuzzer.h"
17 
18 #include <cstdint>
19 #include <memory>
20 #include <string>
21 #include <thread>
22 
23 #include "ability_context_impl.h"
24 #include "data_ability_observer_interface.h"
25 #include "datashare_business_error.h"
26 #include "datashare_helper.h"
27 #include "datashare_predicates.h"
28 #include "datashare_values_bucket.h"
29 #include "media_datashare_ext_ability.h"
30 #include "medialibrary_data_manager.h"
31 #include "media_file_ext_ability.h"
32 #include "media_datashare_stub_impl.h"
33 #include "media_log.h"
34 #include "runtime.h"
35 
36 namespace OHOS {
37 using namespace std;
38 using namespace AbilityRuntime;
39 using namespace DataShare;
40 
41 using namespace FileAccessFwk;
FuzzInt32(const uint8_t * data,size_t size)42 static inline int32_t FuzzInt32(const uint8_t *data, size_t size)
43 {
44     return static_cast<int32_t>(*data);
45 }
46 
FuzzInt64(const uint8_t * data,size_t size)47 static inline int64_t FuzzInt64(const uint8_t *data, size_t size)
48 {
49     return static_cast<int64_t>(*data);
50 }
51 
FuzzDouble(const uint8_t * data,size_t size)52 static inline double FuzzDouble(const uint8_t *data, size_t size)
53 {
54     return static_cast<double>(*data);
55 }
56 
FuzzString(const uint8_t * data,size_t size)57 static inline string FuzzString(const uint8_t *data, size_t size)
58 {
59     return {reinterpret_cast<const char*>(data), size};
60 }
61 
FuzzVectorInt32(const uint8_t * data,size_t size)62 static inline vector<int32_t> FuzzVectorInt32(const uint8_t *data, size_t size)
63 {
64     return {FuzzInt32(data, size)};
65 }
66 
FuzzVectorInt64(const uint8_t * data,size_t size)67 static inline vector<int64_t> FuzzVectorInt64(const uint8_t *data, size_t size)
68 {
69     return {FuzzInt64(data, size)};
70 }
71 
FuzzVectorDouble(const uint8_t * data,size_t size)72 static inline vector<double> FuzzVectorDouble(const uint8_t *data, size_t size)
73 {
74     return {FuzzDouble(data, size)};
75 }
76 
FuzzVectorString(const uint8_t * data,size_t size)77 static inline vector<string> FuzzVectorString(const uint8_t *data, size_t size)
78 {
79     return {FuzzString(data, size)};
80 }
81 
FuzzVectorSingleValueType(const uint8_t * data,size_t size)82 static inline vector<SingleValue::Type> FuzzVectorSingleValueType(const uint8_t *data, size_t size)
83 {
84     return {FuzzInt64(data, size)};
85 }
86 
FuzzVectorMultiValueType(const uint8_t * data,size_t size)87 static inline vector<MutliValue::Type> FuzzVectorMultiValueType(const uint8_t *data, size_t size)
88 {
89     return {
90         FuzzVectorInt32(data, size),
91         FuzzVectorInt64(data, size),
92         FuzzVectorString(data, size),
93         FuzzVectorDouble(data, size)
94     };
95 }
96 
FuzzOperationItem(const uint8_t * data,size_t size)97 static inline OperationItem FuzzOperationItem(const uint8_t *data, size_t size)
98 {
99     return {
100         .operation = FuzzInt32(data, size),
101         .singleParams = FuzzVectorSingleValueType(data, size),
102         .multiParams = FuzzVectorMultiValueType(data, size),
103     };
104 }
105 
FuzzVectorOperationItem(const uint8_t * data,size_t size)106 static inline vector<OperationItem> FuzzVectorOperationItem(const uint8_t *data, size_t size)
107 {
108     return {FuzzOperationItem(data, size)};
109 }
110 
FuzzUri(const uint8_t * data,size_t size)111 static inline Uri FuzzUri(const uint8_t *data, size_t size)
112 {
113     return Uri(FuzzString(data, size));
114 }
115 
FuzzDataSharePredicates(const uint8_t * data,size_t size)116 static inline DataSharePredicates FuzzDataSharePredicates(const uint8_t *data, size_t size)
117 {
118     return DataSharePredicates(FuzzVectorOperationItem(data, size));
119 }
120 
FuzzDataShareValuesBucket(const uint8_t * data,size_t size)121 static inline DataShareValuesBucket FuzzDataShareValuesBucket(const uint8_t *data, size_t size)
122 {
123     return {};
124 }
125 
FuzzVectorDataShareValuesBucket(const uint8_t * data,size_t size)126 static inline vector<DataShareValuesBucket> FuzzVectorDataShareValuesBucket(const uint8_t *data, size_t size)
127 {
128     return {FuzzDataShareValuesBucket(data, size)};
129 }
130 
FuzzDataShareBusinessError(const uint8_t * data,size_t size)131 static inline DatashareBusinessError FuzzDataShareBusinessError(const uint8_t *data, size_t size)
132 {
133     DatashareBusinessError error;
134     error.SetCode(FuzzInt32(data, size));
135     error.SetMessage(FuzzString(data, size));
136     return error;
137 }
138 
NotifyChangeFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)139 static inline void NotifyChangeFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
140 {
141     extension.NotifyChange(FuzzUri(data, size));
142 }
143 
RegisterObserverFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)144 static inline void RegisterObserverFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
145 {
146     sptr<AAFwk::IDataAbilityObserver> dataObserver;
147     extension.RegisterObserver(FuzzUri(data, size), dataObserver);
148 }
149 
UnregisterObserverFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)150 static inline void UnregisterObserverFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
151 {
152     sptr<AAFwk::IDataAbilityObserver> dataObserver;
153     extension.UnregisterObserver(FuzzUri(data, size), dataObserver);
154 }
155 
UpdateFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)156 static inline void UpdateFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
157 {
158     DataSharePredicates predicates;
159     extension.Update(FuzzUri(data, size), FuzzDataSharePredicates(data, size), FuzzDataShareValuesBucket(data, size));
160 }
161 
OpenFileFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)162 static inline void OpenFileFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
163 {
164     extension.OpenFile(FuzzUri(data, size), FuzzString(data, size));
165 }
166 
DeleteFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)167 static inline void DeleteFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
168 {
169     DataSharePredicates predicates;
170     DataShareValuesBucket values;
171     extension.Delete(FuzzUri(data, size), FuzzDataSharePredicates(data, size));
172 }
173 
QueryFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)174 static inline void QueryFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
175 {
176     auto columns = FuzzVectorString(data, size);
177     auto error = FuzzDataShareBusinessError(data, size);
178     extension.Query(FuzzUri(data, size), FuzzDataSharePredicates(data, size), columns, error);
179 }
180 
InsertFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)181 static inline void InsertFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
182 {
183     DataSharePredicates predicates;
184     DataShareValuesBucket values;
185     extension.Insert(FuzzUri(data, size), FuzzDataShareValuesBucket(data, size));
186 }
187 
GetFileTypesFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)188 static inline void GetFileTypesFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
189 {
190     extension.GetFileTypes(FuzzUri(data, size), FuzzString(data, size));
191 }
192 
BatchInsertFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)193 static inline void BatchInsertFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
194 {
195     extension.BatchInsert(FuzzUri(data, size), FuzzVectorDataShareValuesBucket(data, size));
196 }
197 
InsertExtFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)198 static inline void InsertExtFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
199 {
200     string result;
201     extension.InsertExt(FuzzUri(data, size), FuzzDataShareValuesBucket(data, size), result);
202 }
203 
NormalizeUriFuzzer(MediaDataShareExtAbility & extension,const uint8_t * data,size_t size)204 static inline void NormalizeUriFuzzer(MediaDataShareExtAbility &extension, const uint8_t* data, size_t size)
205 {
206     extension.NormalizeUri(FuzzUri(data, size));
207     extension.DenormalizeUri(FuzzUri(data, size));
208 }
209 
StopFuzzer(MediaDataShareExtAbility & extension)210 static inline void StopFuzzer(MediaDataShareExtAbility &extension)
211 {
212     extension.OnStop();
213 }
214 
InitExtention(MediaDataShareExtAbility & extension)215 static int InitExtention(MediaDataShareExtAbility &extension)
216 {
217     extension.InitPermissionHandler();
218     auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
219     auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
220     abilityContextImpl->SetStageContext(stageContext);
221     int32_t sceneCode = 0;
222     return Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl, abilityContextImpl,
223         sceneCode);
224 }
225 
226 class ArkJsRuntime : public AbilityRuntime::JsRuntime {
227 public:
ArkJsRuntime()228     ArkJsRuntime() {};
229 
~ArkJsRuntime()230     ~ArkJsRuntime() {};
231 
StartDebugMode(const DebugOption debugOption)232     void StartDebugMode(const DebugOption debugOption) {};
FinishPreload()233     void FinishPreload() {};
LoadRepairPatch(const string & patchFile,const string & baseFile)234     bool LoadRepairPatch(const string& patchFile, const string& baseFile)
235     {
236         return true;
237     };
NotifyHotReloadPage()238     bool NotifyHotReloadPage()
239     {
240         return true;
241     };
UnLoadRepairPatch(const string & patchFile)242     bool UnLoadRepairPatch(const string& patchFile)
243     {
244         return true;
245     };
RunScript(const string & path,const string & hapPath,bool useCommonChunk=false)246     bool RunScript(const string& path, const string& hapPath, bool useCommonChunk = false)
247     {
248         return true;
249     };
250 };
251 #ifdef FILEEXT
CreateFileFuzzer(MediaFileExtAbility & extension,const uint8_t * data,size_t size)252 static inline void CreateFileFuzzer(MediaFileExtAbility &extension, const uint8_t* data, size_t size)
253 {
254     Uri fuzzUri = FuzzUri(data, size);
255     extension.CreateFile(FuzzUri(data, size), FuzzString(data, size), fuzzUri);
256 }
257 
FileExtInit()258 static inline MediaFileExtAbility FileExtInit()
259 {
260     const std::unique_ptr<ArkJsRuntime> runtime;
261     return {(*runtime)};
262 }
263 #endif
Init()264 static inline MediaDataShareExtAbility Init()
265 {
266     const std::unique_ptr<AbilityRuntime::Runtime> runtime;
267     return {(*runtime)};
268 }
269 
270 } // namespace OHOS
271 
272 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)273 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
274 {
275     /* Run your code on data */
276     auto extension = OHOS::Init();
277     OHOS::InitExtention(extension);
278     OHOS::InsertFuzzer(extension, data, size);
279     OHOS::InsertExtFuzzer(extension, data, size);
280     OHOS::UpdateFuzzer(extension, data, size);
281     OHOS::QueryFuzzer(extension, data, size);
282     OHOS::DeleteFuzzer(extension, data, size);
283     OHOS::OpenFileFuzzer(extension, data, size);
284 
285     OHOS::RegisterObserverFuzzer(extension, data, size);
286     OHOS::UnregisterObserverFuzzer(extension, data, size);
287     OHOS::NotifyChangeFuzzer(extension, data, size);
288 
289     OHOS::GetFileTypesFuzzer(extension, data, size);
290     OHOS::BatchInsertFuzzer(extension, data, size);
291     OHOS::NormalizeUriFuzzer(extension, data, size);
292 #ifdef FILEEXT
293     auto fileExtension = OHOS::FileExtInit();
294     OHOS::CreateFileFuzzer(fileExtension, data, size);
295 #endif
296     OHOS::StopFuzzer(extension);
297     int sleepTime = 100;
298     std::this_thread::sleep_for(std::chrono::microseconds(sleepTime));
299     return 0;
300 }