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 "media_library_duplicate_photo_operation_fuzzer.h"
17
18 #include <cstdint>
19 #include <string>
20 #include <vector>
21 #include <fuzzer/FuzzedDataProvider.h>
22
23 #include "duplicate_photo_operation.h"
24 #include "ability_context_impl.h"
25 #include "rdb_predicates.h"
26 #include "medialibrary_rdbstore.h"
27 #include "deferred_photo_proc_adapter.h"
28 #include "multistages_capture_deferred_photo_proc_session_callback.h"
29
30 #include "medialibrary_app_uri_permission_operations.h"
31 #include "datashare_predicates.h"
32 #include "media_app_uri_permission_column.h"
33 #include "media_column.h"
34 #include "media_file_utils.h"
35 #include "media_log.h"
36 #include "medialibrary_command.h"
37 #include "medialibrary_data_manager.h"
38 #include "medialibrary_errno.h"
39 #include "medialibrary_operation.h"
40 #include "medialibrary_photo_operations.h"
41 #include "medialibrary_unistore.h"
42 #include "medialibrary_unistore_manager.h"
43 #include "medialibrary_kvstore_manager.h"
44 #include "rdb_store.h"
45 #include "rdb_utils.h"
46 #include "userfile_manager_types.h"
47 #include "values_bucket.h"
48
49 namespace OHOS {
50 namespace Media {
51 using namespace std;
52 using namespace DataShare;
53 using namespace OHOS::NativeRdb;
54 using namespace OHOS::RdbDataShareAdapter;
55
56 static const std::string APP_URI_PERMISSION_TABLE = "UriPermission";
57 static const int32_t NUM_BYTES = 1;
58 static const int32_t PERMISSION_DEFAULT = -1;
59 static const int32_t MAX_PERMISSION_TYPE = 6;
60 static const int32_t MAX_DATA = 1;
61
62 FuzzedDataProvider *provider = nullptr;
63 std::shared_ptr<Media::MediaLibraryRdbStore> g_rdbStore;
64
FuzzMimeTypeAndDisplayNameExtension(string & mimeType,string & displayName)65 static inline void FuzzMimeTypeAndDisplayNameExtension(string &mimeType, string &displayName)
66 {
67 uint8_t data = provider->ConsumeIntegralInRange<uint8_t>(0, MAX_DATA);
68 mimeType = MIMETYPE_FUZZER_LISTS[data];
69 displayName = provider->ConsumeBytesAsString(NUM_BYTES) + DISPLAY_NAME_EXTENSION_FUZZER_LISTS[data];
70 }
71
InsertPhotoAsset(string photoId)72 static int32_t InsertPhotoAsset(string photoId)
73 {
74 if (g_rdbStore == nullptr) {
75 return E_ERR;
76 }
77 NativeRdb::ValuesBucket values;
78 values.PutString(Media::PhotoColumn::PHOTO_ID, photoId);
79 values.PutString(Media::MediaColumn::MEDIA_FILE_PATH, provider->ConsumeBytesAsString(NUM_BYTES));
80
81 string mimeType = "undefined";
82 string displayName = ".undefined";
83 FuzzMimeTypeAndDisplayNameExtension(mimeType, displayName);
84 values.PutString(Media::MediaColumn::MEDIA_NAME, displayName);
85 values.PutString(Media::MediaColumn::MEDIA_MIME_TYPE, mimeType);
86
87 int64_t fileId = 0;
88 g_rdbStore->Insert(fileId, Media::PhotoColumn::PHOTOS_TABLE, values);
89 return static_cast<int32_t>(fileId);
90 }
91
FuzzPermissionType()92 static int FuzzPermissionType()
93 {
94 vector<int> vecPermissionType;
95 vecPermissionType.assign(Media::AppUriPermissionColumn::PERMISSION_TYPES_ALL.begin(),
96 Media::AppUriPermissionColumn::PERMISSION_TYPES_ALL.end());
97 vecPermissionType.push_back(PERMISSION_DEFAULT);
98 uint8_t data = provider->ConsumeIntegralInRange<uint8_t>(0, MAX_PERMISSION_TYPE);
99 return vecPermissionType[data];
100 }
101
GetRdbPredicates(void)102 static NativeRdb::RdbPredicates GetRdbPredicates(void)
103 {
104 string photoId = provider->ConsumeBytesAsString(NUM_BYTES);
105 int32_t fileId = InsertPhotoAsset(photoId);
106 string appId = provider->ConsumeBytesAsString(NUM_BYTES);
107 int32_t permissionType = FuzzPermissionType();
108 static DataSharePredicates predicates;
109
110 predicates.And()->EqualTo(Media::AppUriPermissionColumn::APP_ID, appId);
111 predicates.And()->EqualTo(Media::AppUriPermissionColumn::FILE_ID, fileId);
112 predicates.And()->EqualTo(Media::AppUriPermissionColumn::PERMISSION_TYPE, permissionType);
113 NativeRdb::RdbPredicates rdbPredicate = RdbDataShareAdapter::RdbUtils::ToPredicates(predicates,
114 Media::AppUriPermissionColumn::APP_URI_PERMISSION_TABLE);
115 return rdbPredicate;
116 }
117
DuplicatePhotoOperationTest()118 static void DuplicatePhotoOperationTest()
119 {
120 shared_ptr<DuplicatePhotoOperation> duplicatePhotoOperation =
121 make_shared<DuplicatePhotoOperation>();
122 if (duplicatePhotoOperation == nullptr) {
123 MEDIA_ERR_LOG("duplicatePhotoOperation is nullptr.");
124 return;
125 }
126
127 RdbPredicates predicates = GetRdbPredicates();
128 std::vector<string> columns = { provider->ConsumeBytesAsString(NUM_BYTES) };
129
130 duplicatePhotoOperation->GetAllDuplicateAssets(predicates, columns);
131 duplicatePhotoOperation->GetDuplicateAssetsToDelete(predicates, columns);
132 }
133
SetTables()134 static void SetTables()
135 {
136 vector<string> createTableSqlList = {
137 Media::PhotoColumn::CREATE_PHOTO_TABLE,
138 Media::AppUriPermissionColumn::CREATE_APP_URI_PERMISSION_TABLE,
139 Media::AppUriSensitiveColumn::CREATE_APP_URI_SENSITIVE_TABLE,
140 };
141 for (auto &createTableSql : createTableSqlList) {
142 int32_t ret = g_rdbStore->ExecuteSql(createTableSql);
143 if (ret != NativeRdb::E_OK) {
144 MEDIA_ERR_LOG("Execute sql %{private}s failed", createTableSql.c_str());
145 return;
146 }
147 MEDIA_DEBUG_LOG("Execute sql %{private}s success", createTableSql.c_str());
148 }
149 }
150
Init()151 static void Init()
152 {
153 auto stageContext = std::make_shared<AbilityRuntime::ContextImpl>();
154 auto abilityContextImpl = std::make_shared<OHOS::AbilityRuntime::AbilityContextImpl>();
155 abilityContextImpl->SetStageContext(stageContext);
156 int32_t sceneCode = 0;
157 auto ret = Media::MediaLibraryDataManager::GetInstance()->InitMediaLibraryMgr(abilityContextImpl,
158 abilityContextImpl, sceneCode);
159 CHECK_AND_RETURN_LOG(ret == NativeRdb::E_OK, "InitMediaLibrary Mgr failed, ret: %{public}d.", ret);
160 auto rdbStore = Media::MediaLibraryUnistoreManager::GetInstance().GetRdbStore();
161 if (rdbStore == nullptr) {
162 MEDIA_ERR_LOG("rdbStore is nullptr.");
163 return;
164 }
165 g_rdbStore = rdbStore;
166 SetTables();
167 }
168
ClearKvStore()169 static inline void ClearKvStore()
170 {
171 Media::MediaLibraryKvStoreManager::GetInstance().CloseAllKvStore();
172 }
173 } // namespace Media
174 } // namespace OHOS
175
LLVMFuzzerInitialize(int * argc,char *** argv)176 extern "C" int LLVMFuzzerInitialize(int *argc, char ***argv)
177 {
178 OHOS::Media::Init();
179 return 0;
180 }
181
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)182 extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
183 {
184 FuzzedDataProvider fdp(data, size);
185 OHOS::Media::provider = &fdp;
186 if (data == nullptr) {
187 return 0;
188 }
189 OHOS::Media::DuplicatePhotoOperationTest();
190 OHOS::Media::ClearKvStore();
191 return 0;
192 }
193