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