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 "parameter_utils.h"
17
18 #include "medialibrary_errno.h"
19 #include "mimetype_utils.h"
20 #include "media_log.h"
21 #include "media_file_utils.h"
22 #include "photo_album.h"
23 #include "userfile_manager_types.h"
24 #include "media_file_uri.h"
25 #include "medialibrary_common_utils.h"
26 #include "post_event_utils.h"
27
28 namespace OHOS {
29 namespace Media {
30 using namespace std;
31 static const int64_t MAX_INT64 = 9223372036854775807;
32 static const int32_t FORMID_MAX_LEN = 19;
33 static const int32_t EDIT_DATA_MAX_LENGTH = 5 * 1024 * 1024;
34 constexpr size_t MAX_TRASH_PHOTOS_SIZE = 300;
35 constexpr size_t MAX_DELETE_PHOTOS_COMPLETED_SIZE = 500;
36 constexpr int32_t USER_COMMENT_MAX_LEN = 420;
37 const std::unordered_set<int32_t> SUPPORTED_ORIENTATION{0, 90, 180, 270};
38 const int32_t MAX_PHOTO_ID_LEN = 32;
39
CheckFormIds(const vector<string> & formIds)40 int32_t ParameterUtils::CheckFormIds(const vector<string> &formIds)
41 {
42 if (formIds.empty()) {
43 return E_ERR;
44 }
45 for (const auto& formId : formIds) {
46 if (formId.empty() || formId.length() > FORMID_MAX_LEN) {
47 return E_INVALID_ARGUMENTS;
48 }
49 for (uint32_t i = 0; i < formId.length(); i++) {
50 if (!isdigit(formId[i])) {
51 return E_INVALID_ARGUMENTS;
52 }
53 }
54 unsigned long long num = stoull(formId);
55 if (num > MAX_INT64) {
56 return E_INVALID_ARGUMENTS;
57 }
58 }
59 return E_OK;
60 }
61
CheckHighlightAlbum(const DeleteHighLightAlbumsReqBody & reqBody,std::vector<std::string> & albumIds)62 bool ParameterUtils::CheckHighlightAlbum(const DeleteHighLightAlbumsReqBody& reqBody,
63 std::vector<std::string>& albumIds)
64 {
65 bool ret = false;
66 for (size_t i = 0; i < reqBody.albumIds.size(); i++) {
67 PhotoAlbumType photoAlbumType = static_cast<PhotoAlbumType>(reqBody.photoAlbumTypes[i]);
68 PhotoAlbumSubType photoAlbumSubType = static_cast<PhotoAlbumSubType>(reqBody.photoAlbumSubtypes[i]);
69 if (PhotoAlbum::IsHighlightAlbum(photoAlbumType, photoAlbumSubType)) {
70 albumIds.emplace_back(reqBody.albumIds[i]);
71 ret = true;
72 }
73 }
74 return ret;
75 }
76
CheckEditDataLength(const string & editData)77 bool ParameterUtils::CheckEditDataLength(const string& editData)
78 {
79 return editData.size() <= EDIT_DATA_MAX_LENGTH;
80 }
81
CheckOpenUriLength(const string & fileUri)82 bool ParameterUtils::CheckOpenUriLength(const string& fileUri)
83 {
84 return fileUri.size() <= PATH_MAX;
85 }
86
CheckCreateAssetSubtype(int32_t photoSubtype)87 int32_t ParameterUtils::CheckCreateAssetSubtype(int32_t photoSubtype)
88 {
89 if (photoSubtype < static_cast<int32_t>(PhotoSubType::DEFAULT) ||
90 photoSubtype >= static_cast<int32_t>(PhotoSubType::SUBTYPE_END)) {
91 return -EINVAL;
92 }
93 return E_OK;
94 }
95
CheckCreateAssetTitle(const std::string & title,bool isSystem)96 int32_t ParameterUtils::CheckCreateAssetTitle(const std::string &title, bool isSystem)
97 {
98 if (title.empty()) {
99 return E_OK;
100 }
101
102 if (isSystem) {
103 if (MediaFileUtils::CheckTitle(title) != E_OK) {
104 return E_INVALID_DISPLAY_NAME;
105 }
106 return E_OK;
107 }
108
109 if (MediaFileUtils::CheckTitleCompatible(title) != E_OK) {
110 return E_INVALID_DISPLAY_NAME;
111 }
112 return E_OK;
113 }
114
CheckCreateAssetMediaType(int32_t mediaType,const std::string & extension)115 int32_t ParameterUtils::CheckCreateAssetMediaType(int32_t mediaType, const std::string &extension)
116 {
117 if (mediaType != MEDIA_TYPE_IMAGE && mediaType != MEDIA_TYPE_VIDEO) {
118 return -EINVAL;
119 }
120 string mimeType = MimeTypeUtils::GetMimeTypeFromExtension(extension);
121 if (MimeTypeUtils::GetMediaTypeFromMimeType(mimeType) != mediaType) {
122 return E_CHECK_MEDIATYPE_MATCH_EXTENSION_FAIL;
123 }
124 return E_OK;
125 }
126
CheckCreateAssetCameraShotKey(int32_t photoSubtype,const std::string & cameraShotKey)127 int32_t ParameterUtils::CheckCreateAssetCameraShotKey(int32_t photoSubtype, const std::string &cameraShotKey)
128 {
129 if (!cameraShotKey.empty()) {
130 if (cameraShotKey.size() < CAMERA_SHOT_KEY_SIZE ||
131 photoSubtype == static_cast<int32_t>(PhotoSubType::SCREENSHOT)) {
132 return -EINVAL;
133 }
134 }
135 return E_OK;
136 }
137
GetTitleAndExtension(const std::string & displayName,std::string & title,std::string & ext)138 int32_t ParameterUtils::GetTitleAndExtension(const std::string &displayName, std::string &title, std::string &ext)
139 {
140 size_t pos = displayName.find_last_of('.');
141 if (pos != std::string::npos) {
142 title = displayName.substr(0, pos);
143 ext = displayName.substr(pos + 1);
144 return E_OK;
145 }
146 return E_INVALID_DISPLAY_NAME;
147 }
148
CheckPublicCreateAsset(const CreateAssetReqBody & reqBody)149 int32_t ParameterUtils::CheckPublicCreateAsset(const CreateAssetReqBody &reqBody)
150 {
151 int32_t photoSubtype = static_cast<int32_t>(PhotoSubType::DEFAULT);
152 CHECK_AND_RETURN_RET_LOG(reqBody.photoSubtype == photoSubtype, -EINVAL, "Invalid photoSubtype");
153 CHECK_AND_RETURN_RET_LOG(reqBody.displayName.empty(), -EINVAL, "Invalid displayName");
154 CHECK_AND_RETURN_RET_LOG(reqBody.cameraShotKey.empty(), -EINVAL, "Invalid cameraShotKey");
155
156 int32_t errCode = CheckCreateAssetTitle(reqBody.title);
157 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid title");
158 errCode = CheckCreateAssetMediaType(reqBody.mediaType, reqBody.extension);
159 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid mediaType or extension");
160
161 return E_OK;
162 }
163
CheckSystemCreateAsset(const CreateAssetReqBody & reqBody)164 int32_t ParameterUtils::CheckSystemCreateAsset(const CreateAssetReqBody &reqBody)
165 {
166 CHECK_AND_RETURN_RET_LOG(reqBody.title.empty(), -EINVAL, "Invalid title");
167 CHECK_AND_RETURN_RET_LOG(reqBody.extension.empty(), -EINVAL, "Invalid extension");
168
169 int32_t errCode = CheckCreateAssetSubtype(reqBody.photoSubtype);
170 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid photoSubtype");
171 errCode = CheckCreateAssetCameraShotKey(reqBody.photoSubtype, reqBody.cameraShotKey);
172 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid cameraShotKey");
173 errCode = MediaFileUtils::CheckDisplayName(reqBody.displayName);
174 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid displayName");
175 std::string extension = MediaFileUtils::GetExtensionFromPath(reqBody.displayName);
176 CHECK_AND_RETURN_RET_LOG(!extension.empty(), E_INVALID_DISPLAY_NAME, "Invalid extension");
177 errCode = CheckCreateAssetMediaType(reqBody.mediaType, extension);
178 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid mediaType");
179
180 return E_OK;
181 }
182
CheckPublicCreateAssetForApp(const CreateAssetForAppReqBody & reqBody)183 int32_t ParameterUtils::CheckPublicCreateAssetForApp(const CreateAssetForAppReqBody &reqBody)
184 {
185 CHECK_AND_RETURN_RET_LOG(reqBody.displayName.empty(), -EINVAL, "Invalid displayName");
186 CHECK_AND_RETURN_RET_LOG(reqBody.ownerAlbumId.empty(), -EINVAL, "Invalid ownerAlbumId");
187
188 int32_t errCode = CheckCreateAssetSubtype(reqBody.photoSubtype);
189 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid photoSubtype");
190 errCode = CheckCreateAssetTitle(reqBody.title);
191 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid title");
192 errCode = CheckCreateAssetMediaType(reqBody.mediaType, reqBody.extension);
193 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid mediaType or extension");
194
195 return E_OK;
196 }
197
CheckSystemCreateAssetForApp(const CreateAssetForAppReqBody & reqBody)198 int32_t ParameterUtils::CheckSystemCreateAssetForApp(const CreateAssetForAppReqBody &reqBody)
199 {
200 CHECK_AND_RETURN_RET_LOG(reqBody.displayName.empty(), -EINVAL, "Invalid displayName");
201 CHECK_AND_RETURN_RET_LOG(reqBody.ownerAlbumId.empty(), -EINVAL, "Invalid ownerAlbumId");
202
203 int32_t errCode = CheckCreateAssetSubtype(reqBody.photoSubtype);
204 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid photoSubtype");
205 errCode = CheckCreateAssetTitle(reqBody.title, true);
206 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid title");
207 errCode = CheckCreateAssetMediaType(reqBody.mediaType, reqBody.extension);
208 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid mediaType or extension");
209
210 return E_OK;
211 }
212
CheckCreateAssetForAppWithAlbum(const CreateAssetForAppReqBody & reqBody)213 int32_t ParameterUtils::CheckCreateAssetForAppWithAlbum(const CreateAssetForAppReqBody &reqBody)
214 {
215 CHECK_AND_RETURN_RET_LOG(reqBody.displayName.empty(), -EINVAL, "Invalid displayName");
216
217 int32_t errCode = CheckCreateAssetSubtype(reqBody.photoSubtype);
218 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid photoSubtype");
219 errCode = CheckCreateAssetTitle(reqBody.title, true);
220 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid title");
221 errCode = CheckCreateAssetMediaType(reqBody.mediaType, reqBody.extension);
222 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid mediaType or extension");
223
224 return E_OK;
225 }
226
CheckCreatePhotoAlbum(const CreateAlbumReqBody & reqBody)227 int32_t ParameterUtils::CheckCreatePhotoAlbum(const CreateAlbumReqBody &reqBody)
228 {
229 int32_t errCode = MediaFileUtils::CheckAlbumName(reqBody.albumName);
230 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, errCode, "Invalid albumName");
231
232 return E_OK;
233 }
234
CheckTrashPhotos(const std::vector<std::string> & uris)235 int32_t ParameterUtils::CheckTrashPhotos(const std::vector<std::string> &uris)
236 {
237 CHECK_AND_RETURN_RET_LOG(!uris.empty(), -EINVAL, "uris is empty");
238 auto size = uris.size();
239 CHECK_AND_RETURN_RET_LOG(size <= MAX_TRASH_PHOTOS_SIZE, -EINVAL, "Invalid uris size");
240
241 return E_OK;
242 }
243
CheckDeletePhotosCompleted(const std::vector<std::string> & fileIds)244 int32_t ParameterUtils::CheckDeletePhotosCompleted(const std::vector<std::string> &fileIds)
245 {
246 CHECK_AND_RETURN_RET_LOG(!fileIds.empty(), -EINVAL, "fileIds is empty");
247 auto size = fileIds.size();
248 CHECK_AND_RETURN_RET_LOG(size <= MAX_DELETE_PHOTOS_COMPLETED_SIZE, -EINVAL, "Invalid fileIds size");
249
250 return E_OK;
251 }
252
IsPhotoUri(const string & uri)253 bool ParameterUtils::IsPhotoUri(const string& uri)
254 {
255 if (uri.find("../") != string::npos) {
256 return false;
257 }
258 string fileId = MediaFileUri::GetPhotoId(uri);
259 return MediaFileUtils::IsValidInteger(fileId);
260 }
261
CheckSetAssetTitle(const ModifyAssetsReqBody & reqBody)262 int32_t ParameterUtils::CheckSetAssetTitle(const ModifyAssetsReqBody &reqBody)
263 {
264 CHECK_AND_RETURN_RET_LOG(reqBody.fileIds.size() == 1, -EINVAL, "Invalid fileIds");
265 CHECK_AND_RETURN_RET_LOG(!reqBody.title.empty(), E_INVALID_DISPLAY_NAME, "Invalid title");
266 int32_t errCode = MediaFileUtils::CheckTitleCompatible(reqBody.title);
267 CHECK_AND_RETURN_RET_LOG(errCode == E_OK, E_INVALID_DISPLAY_NAME, "Invalid title");
268 return E_OK;
269 }
270
CheckSetAssetPending(const ModifyAssetsReqBody & reqBody)271 int32_t ParameterUtils::CheckSetAssetPending(const ModifyAssetsReqBody &reqBody)
272 {
273 CHECK_AND_RETURN_RET_LOG(reqBody.fileIds.size() == 1, -EINVAL, "Invalid fileIds");
274 CHECK_AND_RETURN_RET_LOG(reqBody.pending >= 0 && reqBody.pending <= 1, -EINVAL, "Invalid pending");
275 return E_OK;
276 }
277
CheckSetAssetsFavorite(const ModifyAssetsReqBody & reqBody)278 int32_t ParameterUtils::CheckSetAssetsFavorite(const ModifyAssetsReqBody &reqBody)
279 {
280 CHECK_AND_RETURN_RET_LOG(!reqBody.fileIds.empty(), -EINVAL, "Invalid fileIds");
281 CHECK_AND_RETURN_RET_LOG(reqBody.favorite >= 0 && reqBody.favorite <= 1, -EINVAL, "Invalid favorite");
282 return E_OK;
283 }
284
CheckSetAssetsHiddenStatus(const ModifyAssetsReqBody & reqBody)285 int32_t ParameterUtils::CheckSetAssetsHiddenStatus(const ModifyAssetsReqBody &reqBody)
286 {
287 CHECK_AND_RETURN_RET_LOG(!reqBody.fileIds.empty(), -EINVAL, "Invalid fileIds");
288 CHECK_AND_RETURN_RET_LOG(reqBody.hiddenStatus >= 0 && reqBody.hiddenStatus <= 1,
289 -EINVAL, "Invalid hiddenStatus");
290 return E_OK;
291 }
292
CheckSetAssetsRecentShowStatus(const ModifyAssetsReqBody & reqBody)293 int32_t ParameterUtils::CheckSetAssetsRecentShowStatus(const ModifyAssetsReqBody &reqBody)
294 {
295 CHECK_AND_RETURN_RET_LOG(!reqBody.fileIds.empty(), -EINVAL, "Invalid fileIds");
296 CHECK_AND_RETURN_RET_LOG(reqBody.recentShowStatus >= 0 && reqBody.recentShowStatus <= 1,
297 -EINVAL, "Invalid recentShowStatus");
298 return E_OK;
299 }
300
CheckSetAssetsUserComment(const ModifyAssetsReqBody & reqBody)301 int32_t ParameterUtils::CheckSetAssetsUserComment(const ModifyAssetsReqBody &reqBody)
302 {
303 CHECK_AND_RETURN_RET_LOG(!reqBody.fileIds.empty(), -EINVAL, "Invalid fileIds");
304 return E_OK;
305 }
306
CheckAddAssetVisitCount(int32_t fileId,int32_t visitType)307 int32_t ParameterUtils::CheckAddAssetVisitCount(int32_t fileId, int32_t visitType)
308 {
309 CHECK_AND_RETURN_RET_LOG(fileId > 0, -EINVAL, "fileId is invalid");
310 CHECK_AND_RETURN_RET_LOG(visitType >= 0 && visitType <= 1, -EINVAL, "Invalid visitType");
311 return E_OK;
312 }
313
CheckUserComment(const AssetChangeReqBody & reqBody)314 int32_t ParameterUtils::CheckUserComment(const AssetChangeReqBody &reqBody)
315 {
316 CHECK_AND_RETURN_RET_LOG(reqBody.fileId > 0, -EINVAL, "fileId is invalid");
317 CHECK_AND_RETURN_RET_LOG(reqBody.userComment.length() <= USER_COMMENT_MAX_LEN, -EINVAL, "user comment too long");
318
319 return E_OK;
320 }
321
CheckCameraShotKey(const AssetChangeReqBody & reqBody)322 int32_t ParameterUtils::CheckCameraShotKey(const AssetChangeReqBody &reqBody)
323 {
324 CHECK_AND_RETURN_RET_LOG(reqBody.fileId > 0, -EINVAL, "fileId is invalid");
325 CHECK_AND_RETURN_RET_LOG(!reqBody.cameraShotKey.empty() && reqBody.cameraShotKey.size() >= CAMERA_SHOT_KEY_SIZE,
326 -EINVAL,
327 "Invalid cameraShotKey");
328
329 return E_OK;
330 }
331
CheckOrientation(const AssetChangeReqBody & reqBody)332 int32_t ParameterUtils::CheckOrientation(const AssetChangeReqBody &reqBody)
333 {
334 CHECK_AND_RETURN_RET_LOG(reqBody.fileId > 0, -EINVAL, "fileId is invalid");
335 CHECK_AND_RETURN_RET_LOG(SUPPORTED_ORIENTATION.count(reqBody.orientation), -EINVAL, "Invalid orientation");
336
337 return E_OK;
338 }
339
CheckVideoEnhancementAttr(const AssetChangeReqBody & reqBody)340 int32_t ParameterUtils::CheckVideoEnhancementAttr(const AssetChangeReqBody &reqBody)
341 {
342 CHECK_AND_RETURN_RET_LOG(reqBody.fileId > 0, -EINVAL, "fileId is invalid");
343 CHECK_AND_RETURN_RET_LOG(reqBody.photoId.size() <= MAX_PHOTO_ID_LEN, -EINVAL, "Invalid photoId");
344
345 return E_OK;
346 }
347
CheckWatermarkType(const AssetChangeReqBody & reqBody)348 int32_t ParameterUtils::CheckWatermarkType(const AssetChangeReqBody &reqBody)
349 {
350 CHECK_AND_RETURN_RET_LOG(reqBody.fileId > 0, -EINVAL, "fileId is invalid");
351 CHECK_AND_RETURN_RET_LOG(
352 MediaFileUtils::CheckSupportedWatermarkType(reqBody.watermarkType), -EINVAL, "Invalid watermarkType");
353
354 return E_OK;
355 }
356
CheckWhereClause(const std::string & whereClause)357 int32_t ParameterUtils::CheckWhereClause(const std::string &whereClause)
358 {
359 int32_t ret = E_OK;
360 MEDIA_DEBUG_LOG("CheckWhereClause start");
361 if (!MediaLibraryCommonUtils::CheckWhereClause(whereClause)) {
362 ret = E_INVALID_VALUES;
363 MEDIA_ERR_LOG("illegal query whereClause input %{private}s", whereClause.c_str());
364 VariantMap map = {
365 {KEY_ERR_FILE, __FILE__}, {KEY_ERR_LINE, __LINE__}, {KEY_ERR_CODE, ret}, {KEY_OPT_TYPE, OptType::QUERY}};
366 PostEventUtils::GetInstance().PostErrorProcess(ErrType::DB_OPT_ERR, map);
367 }
368 MEDIA_DEBUG_LOG("CheckWhereClause end");
369 return ret;
370 }
371
CheckPhotoUri(const string & uri)372 bool ParameterUtils::CheckPhotoUri(const string &uri)
373 {
374 if (uri.find("../") != string::npos) {
375 return false;
376 }
377 string photoUriPrefix = "file://media/Photo/";
378 return MediaFileUtils::StartsWith(uri, photoUriPrefix);
379 }
380
CheckRestore(const RestoreReqBody & reqBody)381 int32_t ParameterUtils::CheckRestore(const RestoreReqBody &reqBody)
382 {
383 CHECK_AND_RETURN_RET_LOG(!reqBody.albumLpath.empty(), E_INVALID_VALUES, "albumLpath is empty.");
384 CHECK_AND_RETURN_RET_LOG(!reqBody.keyPath.empty(), E_INVALID_VALUES, "keyPath is empty.");
385 CHECK_AND_RETURN_RET_LOG(!reqBody.bundleName.empty(), E_INVALID_VALUES, "bundleName is empty.");
386 CHECK_AND_RETURN_RET_LOG(!reqBody.appName.empty(), E_INVALID_VALUES, "appName is empty.");
387 return E_OK;
388 }
389 } // namespace Media
390 } // namespace OHOS