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 "medialibraryclouduploadchecker_fuzzer.h"
17
18 #include <cstdint>
19 #include <string>
20
21 #define private public
22 #include "cloud_upload_checker.h"
23 #undef private
24 #include "ability_context_impl.h"
25 #include "media_log.h"
26 #include "medialibrary_command.h"
27 #include "medialibrary_data_manager.h"
28 #include "medialibrary_rdbstore.h"
29 #include "medialibrary_unistore_manager.h"
30
31 namespace OHOS {
32 using namespace std;
33 using namespace AbilityRuntime;
34 static const string PHOTOS_TABLE = "Photos";
35 static const int32_t E_ERR = -1;
36 std::shared_ptr<Media::MediaLibraryRdbStore> g_rdbStore;
FuzzInt32(const uint8_t * data,size_t size)37 static inline int32_t FuzzInt32(const uint8_t *data, size_t size)
38 {
39 if (data == nullptr || size < sizeof(int32_t)) {
40 return 0;
41 }
42 return static_cast<int32_t>(*data);
43 }
44
FuzzInt64(const uint8_t * data,size_t size)45 static inline int64_t FuzzInt64(const uint8_t *data, size_t size)
46 {
47 if (data == nullptr || size < sizeof(int64_t)) {
48 return 0;
49 }
50 return static_cast<int64_t>(*data);
51 }
52
FuzzString(const uint8_t * data,size_t size)53 static inline string FuzzString(const uint8_t *data, size_t size)
54 {
55 return {reinterpret_cast<const char*>(data), size};
56 }
57
InsertPhotoAsset(const uint8_t * data,size_t size)58 static int32_t InsertPhotoAsset(const uint8_t *data, size_t size)
59 {
60 if (g_rdbStore == nullptr || data == nullptr || size < sizeof(int32_t) + sizeof(int64_t)) {
61 return E_ERR;
62 }
63 int offset = 0;
64 NativeRdb::ValuesBucket values;
65 values.PutString(Media::MediaColumn::MEDIA_FILE_PATH, FuzzString(data, size));
66 values.PutInt(Media::PhotoColumn::PHOTO_DIRTY, FuzzInt32(data + offset, size));
67 offset += sizeof(int64_t);
68 values.PutLong(Media::MediaColumn::MEDIA_SIZE, FuzzInt64(data + offset, size));
69 int64_t fileId = 0;
70 g_rdbStore->Insert(fileId, PHOTOS_TABLE, values);
71 return static_cast<int32_t>(fileId);
72 }
73
FuzzCheckedPhotoInfo(const uint8_t * data,size_t size)74 static Media::CheckedPhotoInfo FuzzCheckedPhotoInfo(const uint8_t *data, size_t size)
75 {
76 Media::CheckedPhotoInfo checkedPhotoInfo = {
77 .fileId = InsertPhotoAsset(data, size),
78 .path = FuzzString(data, size)
79 };
80 return checkedPhotoInfo;
81 }
82
FuzzVectorCheckedPhotoInfo(const uint8_t * data,size_t size)83 static vector<Media::CheckedPhotoInfo> FuzzVectorCheckedPhotoInfo(const uint8_t *data, size_t size)
84 {
85 return {FuzzCheckedPhotoInfo(data, size)};
86 }
87
RepairNoOriginPhotoTest(const uint8_t * data,size_t size)88 static void RepairNoOriginPhotoTest(const uint8_t *data, size_t size)
89 {
90 Media::CloudUploadChecker::QueryLcdPhotoCount(FuzzInt32(data, size));
91 int32_t startFileId = InsertPhotoAsset(data, size);
92 int32_t curFileId = -1;
93 Media::CloudUploadChecker::QueryPhotoInfo(startFileId);
94 Media::CloudUploadChecker::HandlePhotoInfos(FuzzVectorCheckedPhotoInfo(data, size), curFileId);
95 Media::CloudUploadChecker::RepairNoOriginPhoto();
96 }
97
CloudUploadCheckerTest(const uint8_t * data,size_t size)98 static void CloudUploadCheckerTest(const uint8_t *data, size_t size)
99 {
100 RepairNoOriginPhotoTest(data, size);
101 }
102
SetTables()103 void SetTables()
104 {
105 vector<string> createTableSqlList = { Media::PhotoColumn::CREATE_PHOTO_TABLE };
106 for (auto &createTableSql : createTableSqlList) {
107 CHECK_AND_RETURN_LOG(g_rdbStore != nullptr, "g_rdbStore is null");
108 int32_t ret = g_rdbStore->ExecuteSql(createTableSql);
109 if (ret != NativeRdb::E_OK) {
110 MEDIA_ERR_LOG("Execute sql %{private}s failed", createTableSql.c_str());
111 return;
112 }
113 MEDIA_DEBUG_LOG("Execute sql %{private}s success", createTableSql.c_str());
114 }
115 }
116
Init()117 static void Init()
118 {
119 auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
120 auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
121 abilityContextImpl->SetStageContext(stageContext);
122 int32_t sceneCode = 0;
123 auto ret = Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl,
124 abilityContextImpl, sceneCode);
125 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "InitMediaLibraryMgr failed, ret: %{public}d", ret);
126
127 auto rdbStore = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
128 if (rdbStore == nullptr) {
129 MEDIA_ERR_LOG("rdbStore is nullptr");
130 return;
131 }
132 g_rdbStore = rdbStore;
133 SetTables();
134 }
135 } // namespace OHOS
136
LLVMFuzzerInitialize(int * argc,char *** argv)137 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
138 {
139 OHOS::Init();
140 return 0;
141 }
142
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)143 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
144 {
145 OHOS::CloudUploadCheckerTest(data, size);
146 return 0;
147 }