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 #include "medialibrary_thumbnail_fuzzer.h"
16
17 #include <cstdint>
18 #include <string>
19 #include <pixel_map.h>
20
21 #include "ability_context_impl.h"
22 #include "abs_rdb_predicates.h"
23 #include "cloud_thumbnail_observer.h"
24 #include "datashare_helper.h"
25 #include "image_type.h"
26 #include "ithumbnail_helper.h"
27 #include "media_column.h"
28 #include "media_log.h"
29 #include "medialibrary_data_manager.h"
30 #include "medialibrary_unistore_manager.h"
31 #include "rdb_predicates.h"
32 #include "thumbnail_uri_utils.h"
33 #include "userfile_manager_types.h"
34
35 #define private public
36 #include "thumbnail_aging_helper.h"
37 #include "thumbnail_generate_helper.h"
38 #include "thumbnail_generate_worker.h"
39 #include "thumbnail_generate_worker_manager.h"
40 #include "thumbnail_service.h"
41 #include "thumbnail_source_loading.h"
42 #undef private
43
44 namespace OHOS {
45 using namespace std;
46 using namespace DataShare;
47 using namespace DistributedKv;
48 using namespace NativeRdb;
49 using namespace AAFwk;
50 using ChangeType = DataShare::DataShareObserver::ChangeType;
51 using ThumbnailGenerateExecute = void (*)(std::shared_ptr<Media::ThumbnailTaskData> &data);
52 using ThumbnailWorkerPtr = std::shared_ptr<Media::ThumbnailGenerateWorker>;
53 const int32_t PRIORITY_DEFAULT = -1;
54 const int32_t THUMBNAIL_TASK_TYPE_DEFAULT = -1;
55 const string PHOTOS_TABLE = "Photos";
56 const int32_t EVEN = 2;
57 std::shared_ptr<Media::MediaLibraryRdbStore> g_rdbStore;
58
FuzzString(const uint8_t * data,size_t size)59 static inline string FuzzString(const uint8_t *data, size_t size)
60 {
61 return {reinterpret_cast<const char*>(data), size};
62 }
63
FuzzInt32(const uint8_t * data,size_t size)64 static inline int32_t FuzzInt32(const uint8_t *data, size_t size)
65 {
66 if (data == nullptr || size < sizeof(int32_t)) {
67 return 0;
68 }
69 return static_cast<int32_t>(*data);
70 }
71
FuzzInt64(const uint8_t * data,size_t size)72 static inline int64_t FuzzInt64(const uint8_t *data, size_t size)
73 {
74 if (data == nullptr || size < sizeof(int64_t)) {
75 return 0;
76 }
77 return static_cast<int64_t>(*data);
78 }
79
FuzzBool(const uint8_t * data,size_t size)80 static inline bool FuzzBool(const uint8_t* data, size_t size)
81 {
82 if (size == 0) {
83 return false;
84 }
85 return (data[0] % EVEN) == 0;
86 }
87
FuzzThumbnailType(const uint8_t * data,size_t size)88 static inline Media::ThumbnailType FuzzThumbnailType(const uint8_t* data, size_t size)
89 {
90 int32_t value = FuzzInt32(data, size);
91 if (value >= static_cast<int32_t>(Media::ThumbnailType::LCD) &&
92 value <= static_cast<int32_t>(Media::ThumbnailType::THUMB_EX)) {
93 return static_cast<Media::ThumbnailType>(value);
94 }
95 return Media::ThumbnailType::LCD;
96 }
97
FuzzSize(const uint8_t * data,size_t size)98 static inline Media::Size FuzzSize(const uint8_t* data, size_t size)
99 {
100 Media::Size value;
101 const int32_t int32Count = 2;
102 if (data == nullptr || size < sizeof(int32_t) * int32Count) {
103 return value;
104 }
105 int32_t offset = 0;
106 value.width = FuzzInt32(data + offset, size);
107 offset += sizeof(int32_t);
108 value.height = FuzzInt32(data + offset, size);
109 return value;
110 }
111
FuzzPixelFormat(const uint8_t * data,size_t size)112 static inline Media::PixelFormat FuzzPixelFormat(const uint8_t* data, size_t size)
113 {
114 int32_t value = FuzzInt32(data, size);
115 if (value >= static_cast<int32_t>(Media::PixelFormat::UNKNOWN) &&
116 value <= static_cast<int32_t>(Media::PixelFormat::ASTC_8x8)) {
117 return static_cast<Media::PixelFormat>(value);
118 }
119 return Media::PixelFormat::ARGB_8888;
120 }
121
FuzzDecodeOptions(const uint8_t * data,size_t size)122 static inline Media::DecodeOptions FuzzDecodeOptions(const uint8_t* data, size_t size)
123 {
124 Media::DecodeOptions value;
125 value.desiredPixelFormat = FuzzPixelFormat(data, size);
126 return value;
127 }
128
FuzzThumbnailTaskType(const uint8_t * data,size_t size)129 static inline Media::ThumbnailTaskType FuzzThumbnailTaskType(const uint8_t* data, size_t size)
130 {
131 int32_t value = FuzzInt32(data, size);
132 if (value >= static_cast<int32_t>(Media::ThumbnailTaskType::FOREGROUND) &&
133 value <= static_cast<int32_t>(Media::ThumbnailTaskType::BACKGROUND)) {
134 return static_cast<Media::ThumbnailTaskType>(value);
135 }
136 if (value == THUMBNAIL_TASK_TYPE_DEFAULT) {
137 return static_cast<Media::ThumbnailTaskType>(THUMBNAIL_TASK_TYPE_DEFAULT);
138 }
139 return Media::ThumbnailTaskType::FOREGROUND;
140 }
141
FuzzThumbRdbOpt(const uint8_t * data,size_t size,bool isNeedNullptr)142 static Media::ThumbRdbOpt FuzzThumbRdbOpt(const uint8_t* data, size_t size, bool isNeedNullptr)
143 {
144 std::shared_ptr<Media::MediaLibraryRdbStore> store;
145 if (isNeedNullptr) {
146 store = FuzzBool(data, size) ?
147 Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore() : nullptr;
148 } else {
149 store = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
150 }
151
152 Media::ThumbRdbOpt opt = {
153 .store = store,
154 .networkId = FuzzString(data, size),
155 .path = FuzzString(data, size),
156 .table = FuzzBool(data, size) ? PHOTOS_TABLE : FuzzString(data, size),
157 .row = FuzzString(data, size),
158 .dateTaken = FuzzString(data, size),
159 .fileUri = FuzzString(data, size)
160 };
161 return opt;
162 }
163
FuzzMediaType(const uint8_t * data,size_t size)164 static inline Media::MediaType FuzzMediaType(const uint8_t* data, size_t size)
165 {
166 int32_t value = FuzzInt32(data, size);
167 if (value >= static_cast<int32_t>(Media::MediaType::MEDIA_TYPE_FILE) &&
168 value <= static_cast<int32_t>(Media::MediaType::MEDIA_TYPE_DEFAULT)) {
169 return static_cast<Media::MediaType>(value);
170 }
171 return Media::MediaType::MEDIA_TYPE_IMAGE;
172 }
173
FuzzThumbnailData(const uint8_t * data,size_t size)174 static Media::ThumbnailData FuzzThumbnailData(const uint8_t* data, size_t size)
175 {
176 Media::ThumbnailData datas;
177 datas.path = FuzzString(data, size);
178 datas.mediaType = FuzzMediaType(data, size);
179 return datas;
180 }
181
FuzzThumbnailTaskPriority(const uint8_t * data,size_t size)182 static Media::ThumbnailTaskPriority FuzzThumbnailTaskPriority(const uint8_t* data, size_t size)
183 {
184 int32_t value = FuzzInt32(data, size);
185 if (value >= static_cast<int32_t>(Media::ThumbnailTaskPriority::HIGH) &&
186 value <= static_cast<int32_t>(Media::ThumbnailTaskPriority::LOW)) {
187 return static_cast<Media::ThumbnailTaskPriority>(value);
188 }
189 if (value == PRIORITY_DEFAULT) {
190 return static_cast<Media::ThumbnailTaskPriority>(PRIORITY_DEFAULT);
191 }
192 return Media::ThumbnailTaskPriority::LOW;
193 }
194
ThumbnailAgingHelperTest(const uint8_t * data,size_t size)195 static void ThumbnailAgingHelperTest(const uint8_t* data, size_t size)
196 {
197 const int64_t int64Count = 2;
198 if (data == nullptr || size < sizeof(int32_t) + sizeof(int64_t) * int64Count) {
199 return;
200 }
201 Media::ThumbRdbOpt opt = FuzzThumbRdbOpt(data, size, false);
202 Media::ThumbnailAgingHelper::AgingLcdBatch(opt);
203 int64_t offset = 0;
204 int64_t time = FuzzInt64(data + offset, size);
205 bool before = FuzzBool(data, size);
206 int outLcdCount;
207 Media::ThumbnailAgingHelper::GetAgingDataCount(time, before, opt, outLcdCount);
208
209 vector<Media::ThumbnailData> infos;
210 offset += sizeof(int32_t);
211 Media::ThumbnailAgingHelper::GetAgingLcdData(opt, FuzzInt32(data + offset, size), infos);
212 offset += sizeof(int64_t);
213 Media::ThumbnailAgingHelper::GetLcdCountByTime(FuzzInt64(data + offset, size), FuzzBool(data, size),
214 opt, outLcdCount);
215 }
216
ThumbnailGenerateHelperTest(const uint8_t * data,size_t size)217 static void ThumbnailGenerateHelperTest(const uint8_t* data, size_t size)
218 {
219 Media::ThumbRdbOpt opts = FuzzThumbRdbOpt(data, size, true);
220 Media::ThumbnailGenerateHelper::CreateThumbnailFileScaned(opts, FuzzBool(data, size));
221 Media::ThumbnailGenerateHelper::CreateThumbnailBackground(opts);
222 Media::ThumbnailGenerateHelper::CreateAstcBackground(opts);
223 Media::ThumbnailGenerateHelper::CreateAstcCloudDownload(opts, FuzzBool(data, size));
224 RdbPredicates predicates(PHOTOS_TABLE);
225 Media::ThumbnailGenerateHelper::CreateLcdBackground(opts);
226 int32_t outLcdCount;
227 Media::ThumbnailGenerateHelper::GetLcdCount(opts, outLcdCount);
228 vector<Media::ThumbnailData> outDatas;
229 Media::ThumbnailGenerateHelper::GetNoLcdData(opts, outDatas);
230 outDatas.clear();
231 Media::ThumbnailGenerateHelper::GetNoThumbnailData(opts, outDatas);
232 outDatas.clear();
233 Media::ThumbnailGenerateHelper::GetNoAstcData(opts, outDatas);
234 int64_t time = FuzzInt64(data, size);
235 int32_t count;
236 Media::ThumbnailGenerateHelper::GetNewThumbnailCount(opts, time, count);
237 Media::ThumbnailData thumbData = FuzzThumbnailData(data, size);
238 string fileName;
239 Media::ThumbnailGenerateHelper::GetAvailableFile(opts, thumbData, FuzzThumbnailType(data, size), fileName);
240 Media::ThumbnailGenerateHelper::GetThumbnailPixelMap(opts, FuzzThumbnailType(data, size));
241 Media::ThumbnailGenerateHelper::UpgradeThumbnailBackground(opts, FuzzBool(data, size));
242 Media::ThumbnailGenerateHelper::RestoreAstcDualFrame(opts);
243 outDatas.clear();
244 Media::ThumbnailGenerateHelper::GetThumbnailDataNeedUpgrade(opts, outDatas, FuzzBool(data, size));
245 Media::ThumbnailGenerateHelper::CheckMonthAndYearKvStoreValid(opts);
246 }
247
ThumbnailGenerateWorkerTest(const uint8_t * data,size_t size)248 static void ThumbnailGenerateWorkerTest(const uint8_t* data, size_t size)
249 {
250 Media::ThumbRdbOpt opts = FuzzThumbRdbOpt(data, size, false);
251 Media::ThumbnailData thumbnailData = FuzzThumbnailData(data, size);
252 std::shared_ptr<Media::ThumbnailTaskData> taskData =
253 std::make_shared<Media::ThumbnailTaskData>(opts, thumbnailData, FuzzInt32(data, size));
254 std::shared_ptr<Media::ThumbnailGenerateTask> task =
255 std::make_shared<Media::ThumbnailGenerateTask>(Media::IThumbnailHelper::CreateLcdAndThumbnail, taskData);
256
257 std::shared_ptr<Media::ThumbnailGenerateWorker> workerPtr = std::make_shared<Media::ThumbnailGenerateWorker>();
258 Media::ThumbnailTaskPriority priority = FuzzThumbnailTaskPriority(data, size);
259 workerPtr->AddTask(task, priority);
260 workerPtr->ReleaseTaskQueue(priority);
261 }
262
ThumbnailGenerateWorkerManagerTest(const uint8_t * data,size_t size)263 static void ThumbnailGenerateWorkerManagerTest(const uint8_t* data, size_t size)
264 {
265 Media::ThumbnailTaskType type = FuzzThumbnailTaskType(data, size);
266 auto& manager = Media::ThumbnailGenerateWorkerManager::GetInstance();
267 manager.InitThumbnailWorker(type);
268 manager.ClearAllTask();
269
270 manager.InitThumbnailWorker(type);
271 manager.TryCloseThumbnailWorkerTimer();
272 }
273
SetTables()274 void SetTables()
275 {
276 vector<string> createTableSqlList = { Media::PhotoColumn::CREATE_PHOTO_TABLE };
277 for (auto &createTableSql : createTableSqlList) {
278 int32_t ret = g_rdbStore->ExecuteSql(createTableSql);
279 if (ret != NativeRdb::E_OK) {
280 MEDIA_ERR_LOG("Execute sql %{private}s failed", createTableSql.c_str());
281 return;
282 }
283 MEDIA_DEBUG_LOG("Execute sql %{private}s success", createTableSql.c_str());
284 }
285 }
286
Init()287 static void Init()
288 {
289 auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
290 auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
291 abilityContextImpl->SetStageContext(stageContext);
292 int32_t sceneCode = 0;
293 auto ret = Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl,
294 abilityContextImpl, sceneCode);
295 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "InitMediaLibraryMgr failed, ret: %{public}d", ret);
296
297 auto rdbStore = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
298 if (rdbStore == nullptr) {
299 MEDIA_ERR_LOG("rdbStore is nullptr");
300 return;
301 }
302 g_rdbStore = rdbStore;
303 SetTables();
304 }
305
ThumhnailTest(const uint8_t * data,size_t size)306 static void ThumhnailTest(const uint8_t* data, size_t size)
307 {
308 const int32_t int32Count = 4;
309 if (data == nullptr || size < sizeof(int32_t) * int32Count) {
310 return;
311 }
312 int32_t offset = 0;
313 Media::ThumbnailService::GetInstance()->GetThumbnailFd(FuzzString(data, size),
314 FuzzInt32(data + offset, size));
315 string thumUri = "file://media/Photo/1?operation=thumbnail&width=-1&height=-1";
316 offset += sizeof(int32_t);
317 Media::ThumbnailService::GetInstance()->GetThumbnailFd(thumUri, FuzzInt32(data + offset, size));
318 Media::ThumbnailService::GetInstance()->LcdAging();
319 offset += sizeof(int32_t);
320 Media::ThumbnailService::GetInstance()->CreateThumbnailFileScaned(FuzzString(data, size),
321 FuzzString(data, size), FuzzInt32(data + offset, size));
322 offset += sizeof(int32_t);
323 NativeRdb::RdbPredicates rdbPredicate("Photos");
324 Media::ThumbnailService::GetInstance()->CancelAstcBatchTask(FuzzInt32(data + offset, size));
325 Media::ThumbnailService::GetInstance()->GenerateThumbnailBackground();
326 Media::ThumbnailService::GetInstance()->UpgradeThumbnailBackground(false);
327 Media::ThumbnailService::GetInstance()->RestoreThumbnailDualFrame();
328 Media::ThumbnailService::GetInstance()->CheckCloudThumbnailDownloadFinish();
329 Media::ThumbnailService::GetInstance()->InterruptBgworker();
330 }
331
ThumbnailSourceTest(const uint8_t * data,size_t size)332 static void ThumbnailSourceTest(const uint8_t* data, size_t size)
333 {
334 Media::GetLocalThumbnailPath(FuzzString(data, size), FuzzString(data, size));
335 int32_t error;
336 int32_t minSize = FuzzInt32(data, size);
337 Media::ThumbnailData thumbnailData = FuzzThumbnailData(data, size);
338 Media::LocalThumbSource::GetSourcePath(thumbnailData, error);
339 Media::LocalThumbSource::IsSizeLargeEnough(thumbnailData, minSize);
340 thumbnailData = FuzzThumbnailData(data, size);
341 Media::LocalLcdSource::GetSourcePath(thumbnailData, error);
342 Media::LocalLcdSource::IsSizeLargeEnough(thumbnailData, minSize);
343 thumbnailData = FuzzThumbnailData(data, size);
344 Media::LocalOriginSource::GetSourcePath(thumbnailData, error);
345 Media::LocalOriginSource::IsSizeLargeEnough(thumbnailData, minSize);
346
347 thumbnailData = FuzzThumbnailData(data, size);
348 Media::CloudThumbSource::GetSourcePath(thumbnailData, error);
349 Media::CloudThumbSource::IsSizeLargeEnough(thumbnailData, minSize);
350
351 thumbnailData = FuzzThumbnailData(data, size);
352 Media::CloudLcdSource::GetSourcePath(thumbnailData, error);
353 Media::CloudLcdSource::IsSizeLargeEnough(thumbnailData, minSize);
354
355 thumbnailData = FuzzThumbnailData(data, size);
356 Media::CloudOriginSource::GetSourcePath(thumbnailData, error);
357 Media::CloudOriginSource::IsSizeLargeEnough(thumbnailData, minSize);
358 Media::NeedAutoResize(FuzzSize(data, size));
359
360 Media::DecodeOptions decodeOpts = FuzzDecodeOptions(data, size);
361 Media::GenDecodeOpts(FuzzSize(data, size), FuzzSize(data, size), decodeOpts);
362
363 thumbnailData = FuzzThumbnailData(data, size);
364 Media::Size sourceSize = FuzzSize(data, size);
365 Media::Size desiredSize = FuzzSize(data, size);
366 Media::ConvertDecodeSize(thumbnailData, sourceSize, desiredSize);
367 uint32_t err = 0;
368 Media::LoadImageSource(FuzzString(data, size), err);
369 desiredSize = FuzzSize(data, size);
370 thumbnailData = FuzzThumbnailData(data, size);
371 Media::SourceLoader sourceLoader(desiredSize, thumbnailData);
372 sourceLoader.CreateVideoFramePixelMap();
373 sourceLoader.SetCurrentStateFunction();
374 }
375
ParseFileUriTest(const uint8_t * data,size_t size)376 static void ParseFileUriTest(const uint8_t* data, size_t size)
377 {
378 string outFileId;
379 string outNetworkId;
380 string outTableName;
381 string uri = "file://media/Photo/2";
382 Media::ThumbnailUriUtils::ParseFileUri(uri, outFileId, outNetworkId, outTableName);
383 Media::ThumbnailUriUtils::GetDateTakenFromUri(FuzzString(data, size));
384 Media::ThumbnailUriUtils::GetFileUriFromUri(FuzzString(data, size));
385 }
386 } // namespace OHOS
387
LLVMFuzzerInitialize(int * argc,char *** argv)388 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
389 {
390 OHOS::Init();
391 return 0;
392 }
393
394 /* Fuzzer entry point */
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)395 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
396 {
397 /* Run your code on data */
398 OHOS::ThumhnailTest(data, size);
399 OHOS::ThumbnailAgingHelperTest(data, size);
400 OHOS::ThumbnailGenerateHelperTest(data, size);
401 OHOS::ThumbnailGenerateWorkerTest(data, size);
402 OHOS::ThumbnailGenerateWorkerManagerTest(data, size);
403 OHOS::ThumbnailSourceTest(data, size);
404 OHOS::ParseFileUriTest(data, size);
405 return 0;
406 }