1 /*
2 * Copyright (c) 2024 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 "hap_verify_utils.h"
17
18 #include <algorithm>
19 #include <optional>
20 #include <set>
21
22 #include "hap_verify_info.h"
23 #include "log.h"
24 #include "utils.h"
25
26 namespace OHOS {
27 namespace AppPackingTool {
28 namespace {
29 const std::string ENTRY = "entry";
30 const std::string FEATURE = "feature";
31 const std::string SHARED_LIBRARY = "shared";
32 const std::string EMPTY_STRING = "";
33 const std::string REFERENCE_LINK = "FAQ";
34 const std::string INCLUDE = "include";
35 const std::string EXCLUDE = "exclude";
36 const std::string MODULE_NAME = "moduleName";
37 const std::string PACKAGE_NAME = "packageName";
38 const std::string ENTRY_NAME = "entryName";
39 const std::string ATOMIC_SERVICE = "atomicService";
40 const std::string TYPE_SHARED = "shared";
41 const std::string HAR = "har";
42 const std::string HAP_SUFFIX = ".hap";
43 const std::string HSP_SUFFIX = ".hsp";
44 const std::string APP_PLUGIN = "appPlugin";
45 const int32_t TWO = 2;
46 const long FILE_LENGTH_1KB = 1024L;
47 }
48
CheckHapIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)49 bool HapVerifyUtils::CheckHapIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
50 {
51 if (hapVerifyInfos.empty()) {
52 LOGE("hapVerifyInfos is empty!");
53 return false;
54 }
55 if (!CheckIsPluginApp(hapVerifyInfos)) {
56 LOGE("CheckIsPluginApp failed");
57 return false;
58 }
59 if (!CheckAppFieldsIsSame(hapVerifyInfos)) {
60 LOGE("CheckAppFieldsIsSame failed!");
61 return false;
62 }
63 if (!CheckModuleNameIsValid(hapVerifyInfos)) {
64 LOGE("CheckModuleNameIsValid failed!");
65 return false;
66 }
67 if (!CheckPackageNameIsValid(hapVerifyInfos)) {
68 LOGE("CheckPackageNameIsValid failed! PackageName duplicated.");
69 return false;
70 }
71 if (!CheckEntryIsValid(hapVerifyInfos)) {
72 LOGE("CheckEntryIsValid failed!");
73 return false;
74 }
75 if (!CheckDependencyIsValid(hapVerifyInfos)) {
76 LOGE("CheckDependencyIsValid failed!");
77 return false;
78 }
79 if (!CheckAtomicServiceIsValid(hapVerifyInfos)) {
80 LOGE("CheckAtomicServiceIsValid failed.");
81 return false;
82 }
83 if (!CheckAbilityNameIsValid(hapVerifyInfos)) {
84 LOGI("CheckAbilityNameIsValid failed. Ability name is duplicated.");
85 }
86 if (!CheckTargetModuleNameIsExisted(hapVerifyInfos)) {
87 LOGE("CheckTargetModuleNameIsExisted failed. Target module is not found.");
88 return false;
89 }
90 if (!CheckCompileSdkIsValid(hapVerifyInfos)) {
91 LOGE("CheckCompileSdkIsValid failed. Compile sdk config is not same.");
92 return false;
93 }
94 if (!CheckProxyDataUriIsUnique(hapVerifyInfos)) {
95 LOGE("CheckProxyDataUriIsUnique failed. Uris in proxy data are not unique.");
96 return false;
97 }
98 if (!CheckContinueTypeIsValid(hapVerifyInfos)) {
99 LOGE("CheckContinueTypeIsValid failed.");
100 return false;
101 }
102 return true;
103 }
104
CheckIsPluginApp(const std::list<HapVerifyInfo> & hapVerifyInfos)105 bool HapVerifyUtils::CheckIsPluginApp(const std::list<HapVerifyInfo>& hapVerifyInfos)
106 {
107 auto it = std::find_if(hapVerifyInfos.begin(), hapVerifyInfos.end(),
108 [](const HapVerifyInfo& hapVerifyInfo) {
109 return hapVerifyInfo.GetBundleType() == APP_PLUGIN;
110 });
111 if (it != hapVerifyInfos.end()) {
112 if (hapVerifyInfos.size() != 1) {
113 LOGE("plugin App must contain only one element");
114 return false;
115 }
116 HapVerifyInfo hapVerifyInfo = *hapVerifyInfos.begin();
117 if (hapVerifyInfo.GetFileType() != HSP_SUFFIX) {
118 LOGE("plugin App must be of type hsp");
119 return false;
120 }
121 }
122 return true;
123 }
124
CheckAppFieldsIsSame(const std::list<HapVerifyInfo> & hapVerifyInfos)125 bool HapVerifyUtils::CheckAppFieldsIsSame(const std::list<HapVerifyInfo>& hapVerifyInfos)
126 {
127 if (hapVerifyInfos.empty()) {
128 LOGE("hapVerifyInfos is empty!");
129 return false;
130 }
131 std::list<HapVerifyInfo> hapList;
132 std::list<HapVerifyInfo> hspList;
133 int32_t hspMinCompatibleVersionCodeMax = -1;
134 int32_t hspTargetApiVersionMax = -1;
135 int32_t hspMinApiVersionMax = -1;
136 HapVerifyInfo hapVerifyInfo = *hapVerifyInfos.begin();
137 VerifyCollection verifyCollection;
138 verifyCollection.bundleName = hapVerifyInfo.GetBundleName();
139 verifyCollection.bundleType = hapVerifyInfo.GetBundleType();
140 verifyCollection.vendor = hapVerifyInfo.GetVendor();
141 verifyCollection.versionCode = hapVerifyInfo.GetVersion().versionCode;
142 verifyCollection.versionName = hapVerifyInfo.GetVersion().versionName;
143 verifyCollection.compatibleApiVersion = hapVerifyInfo.GetApiVersion().compatibleApiVersion;
144 verifyCollection.releaseType = hapVerifyInfo.GetApiVersion().releaseType;
145 verifyCollection.targetBundleName = hapVerifyInfo.GetTargetBundleName();
146 verifyCollection.targetPriority = hapVerifyInfo.GetTargetPriority();
147 verifyCollection.debug = hapVerifyInfo.IsDebug();
148 verifyCollection.moduleName = hapVerifyInfo.GetModuleName();
149 verifyCollection.moduleType = hapVerifyInfo.GetModuleType();
150 verifyCollection.multiAppMode = hapVerifyInfo.GetMultiAppMode();
151 std::list<std::string> assetAccessGroups = hapVerifyInfo.GetAssetAccessGroups();
152 std::string moduleName = hapVerifyInfo.GetModuleName();
153 auto it = std::find_if(hapVerifyInfos.begin(), hapVerifyInfos.end(),
154 [](const HapVerifyInfo& hapVerifyInfo) {
155 return hapVerifyInfo.GetModuleType() == ENTRY;
156 });
157 std::optional<HapVerifyInfo> entryOptional;
158 if (it != hapVerifyInfos.end()) {
159 entryOptional.emplace(*it);
160 if (entryOptional.has_value()) {
161 moduleName = entryOptional.value().GetModuleName();
162 assetAccessGroups = entryOptional.value().GetAssetAccessGroups();
163 }
164 }
165 for (HapVerifyInfo hapVerifyInfo : hapVerifyInfos) {
166 if (!AppFieldsIsSame(verifyCollection, hapVerifyInfo)) {
167 LOGW("Module: (%s) and Module: (%s) has different values.",
168 verifyCollection.moduleName.c_str(), hapVerifyInfo.GetModuleName().c_str());
169 return false;
170 }
171 if (!AppAssetAccessGroupsIsSame(assetAccessGroups, hapVerifyInfo)) {
172 LOGW("Module: (%s) and Module: (%s) has different values.",
173 moduleName.c_str(), hapVerifyInfo.GetModuleName().c_str());
174 }
175 if (hapVerifyInfo.GetFileType() == HAP_SUFFIX) {
176 hapList.emplace_back(hapVerifyInfo);
177 } else if (hapVerifyInfo.GetFileType() == HSP_SUFFIX) {
178 hspList.emplace_back(hapVerifyInfo);
179 if (hapVerifyInfo.GetVersion().minCompatibleVersionCode > hspMinCompatibleVersionCodeMax) {
180 hspMinCompatibleVersionCodeMax = hapVerifyInfo.GetVersion().minCompatibleVersionCode;
181 }
182 if (hapVerifyInfo.GetApiVersion().targetApiVersion > hspTargetApiVersionMax) {
183 hspTargetApiVersionMax = hapVerifyInfo.GetApiVersion().targetApiVersion;
184 }
185 if (hapVerifyInfo.GetApiVersion().compatibleApiVersion > hspMinApiVersionMax) {
186 hspMinApiVersionMax = hapVerifyInfo.GetApiVersion().compatibleApiVersion;
187 }
188 }
189 }
190 if (!AppFieldsIsValid(hapList, hspMinCompatibleVersionCodeMax, hspTargetApiVersionMax, hspMinApiVersionMax)) {
191 return false;
192 }
193 if (!ModuleDebugValidation(hapList, hspList)) {
194 return false;
195 }
196 return true;
197 }
198
ModuleDebugValidation(const std::list<HapVerifyInfo> hapList,const std::list<HapVerifyInfo> hspList)199 bool HapVerifyUtils::ModuleDebugValidation(const std::list<HapVerifyInfo> hapList,
200 const std::list<HapVerifyInfo> hspList)
201 {
202 if (hapList.empty()) {
203 LOGW("hapList empty");
204 return true;
205 }
206 HapVerifyInfo hap = *hapList.begin();
207 for (const HapVerifyInfo& hapInfo : hapList) {
208 if (hap.IsDebug() != hapInfo.IsDebug()) {
209 LOGE("The debug fields of multiple Hap are different.");
210 return false;
211 }
212 }
213 if (hap.IsDebug() || hspList.empty()) {
214 LOGW("hap debug is true or hspList empty");
215 return true;
216 }
217 for (const HapVerifyInfo& hapInfo : hspList) {
218 if (hapInfo.IsDebug()) {
219 LOGE("Detected HAP(s) with debug=false, but some HSP(s) are debug=true.");
220 return false;
221 }
222 }
223 return true;
224 }
225
AppFieldsIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos,int32_t minCompatibleVersionCode,int32_t targetApiVersion,int32_t minApiVersion)226 bool HapVerifyUtils::AppFieldsIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos,
227 int32_t minCompatibleVersionCode, int32_t targetApiVersion, int32_t minApiVersion)
228 {
229 if (hapVerifyInfos.empty()) {
230 LOGW("hapList empty");
231 return true;
232 }
233 HapVerifyInfo hap = *hapVerifyInfos.begin();
234 for (const HapVerifyInfo& hapInfo : hapVerifyInfos) {
235 if (hap.GetVersion().minCompatibleVersionCode != hapInfo.GetVersion().minCompatibleVersionCode ||
236 hap.GetApiVersion().targetApiVersion != hapInfo.GetApiVersion().targetApiVersion ||
237 hap.GetApiVersion().compatibleApiVersion != hapInfo.GetApiVersion().compatibleApiVersion) {
238 LOGE("hap minCompatibleVersionCode or targetApiVersion or minApiVersion different");
239 return false;
240 }
241 }
242 if (hap.GetVersion().minCompatibleVersionCode < minCompatibleVersionCode ||
243 hap.GetApiVersion().targetApiVersion < targetApiVersion ||
244 hap.GetApiVersion().compatibleApiVersion < minApiVersion) {
245 LOGE("minCompatibleVersionCode or targetApiVersion or minApiVersion property hap less than hsp");
246 return false;
247 }
248 return true;
249 }
250
AppFieldsIsSame(const VerifyCollection & verifyCollection,const HapVerifyInfo & hapVerifyInfo)251 bool HapVerifyUtils::AppFieldsIsSame(const VerifyCollection& verifyCollection, const HapVerifyInfo& hapVerifyInfo)
252 {
253 if (hapVerifyInfo.GetBundleName().empty()) {
254 LOGE("bundleName is empty");
255 return false;
256 }
257 if (verifyCollection.bundleName != hapVerifyInfo.GetBundleName()) {
258 LOGE("input module bundleName is different.");
259 return false;
260 }
261 if (verifyCollection.bundleType != hapVerifyInfo.GetBundleType()) {
262 LOGE("input module bundleType is different.");
263 return false;
264 }
265 if (verifyCollection.versionCode != hapVerifyInfo.GetVersion().versionCode) {
266 LOGE("input module versionCode is different.");
267 return false;
268 }
269 if (verifyCollection.releaseType != hapVerifyInfo.GetApiVersion().releaseType) {
270 LOGE("input module releaseType is different.");
271 LOGE("Solutions: > Check if the releaseType" \
272 " is the same in different modules.");
273 return false;
274 }
275 if (verifyCollection.targetBundleName != hapVerifyInfo.GetTargetBundleName()) {
276 LOGE("targetBundleName is different.");
277 return false;
278 }
279 if (verifyCollection.targetPriority != hapVerifyInfo.GetTargetPriority()) {
280 LOGE("targetPriority is different.");
281 return false;
282 }
283 if (IsEntryOrFeature(verifyCollection.moduleType) && IsEntryOrFeature(hapVerifyInfo.GetModuleType())) {
284 if (verifyCollection.multiAppMode != (hapVerifyInfo.GetMultiAppMode())) {
285 LOGE("multiAppMode is different.");
286 return false;
287 }
288 }
289 return true;
290 }
291
AppAssetAccessGroupsIsSame(const std::list<std::string> & assetAccessGroups,const HapVerifyInfo & hapVerifyInfo)292 bool HapVerifyUtils::AppAssetAccessGroupsIsSame(const std::list<std::string>& assetAccessGroups,
293 const HapVerifyInfo& hapVerifyInfo)
294 {
295 std::set<std::string> inputSet(assetAccessGroups.begin(), assetAccessGroups.end());
296 std::set<std::string> infoSet(hapVerifyInfo.GetAssetAccessGroups().begin(),
297 hapVerifyInfo.GetAssetAccessGroups().end());
298
299 if (inputSet != infoSet) {
300 LOGW("input module assetAccessGroups is different.");
301 return false;
302 }
303 return true;
304 }
305
IsEntryOrFeature(const std::string & moduleType)306 bool HapVerifyUtils::IsEntryOrFeature(const std::string& moduleType)
307 {
308 return ((moduleType == ENTRY) || (moduleType == FEATURE));
309 }
310
ShowCheckTips(const HapVerifyInfo & hapVerifyInfo1,const HapVerifyInfo & hapVerifyInfo2,const std::string & tip)311 void HapVerifyUtils::ShowCheckTips(const HapVerifyInfo& hapVerifyInfo1, const HapVerifyInfo& hapVerifyInfo2,
312 const std::string& tip)
313 {
314 LOGE("Module: (%s) and Module: (%s) have the same %s, "
315 "please check deviceType or distroFilter/distributionFilter of the module.",
316 hapVerifyInfo1.GetModuleName().c_str(), hapVerifyInfo2.GetModuleName().c_str(), tip.c_str());
317 LOGE("Module: %s has deviceType %s.", hapVerifyInfo1.GetModuleName().c_str(),
318 Utils::ListToString(hapVerifyInfo1.GetDeviceTypes()).c_str());
319 LOGE("Another Module: %s has deviceType %s.", hapVerifyInfo2.GetModuleName().c_str(),
320 Utils::ListToString(hapVerifyInfo2.GetDeviceTypes()).c_str());
321 if (hapVerifyInfo1.GetDistroFilter().Dump() != EMPTY_STRING) {
322 LOGE("Module: %s DistroFilter/DistributionFilter is : %s.", hapVerifyInfo1.GetModuleName().c_str(),
323 hapVerifyInfo1.GetDistroFilter().Dump().c_str());
324 }
325 if (hapVerifyInfo2.GetDistroFilter().Dump() != EMPTY_STRING) {
326 LOGE("Another Module: %s DistroFilter/DistributionFilter is %s.", hapVerifyInfo2.GetModuleName().c_str(),
327 hapVerifyInfo2.GetDistroFilter().Dump().c_str());
328 }
329 LOGE("Solution: Make sure the %s is valid and unique.", tip.c_str());
330 LOGE("Reference: %s.", REFERENCE_LINK.c_str());
331 }
332
CheckModuleNameIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)333 bool HapVerifyUtils::CheckModuleNameIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
334 {
335 for (auto iter1 = hapVerifyInfos.begin(); iter1 != hapVerifyInfos.end(); iter1++) {
336 const HapVerifyInfo& hapVerifyInfo1 = *iter1;
337 if (hapVerifyInfo1.GetModuleName().empty()) {
338 LOGE("module name can not be empty.");
339 return false;
340 }
341 for (auto iter2 = std::next(iter1); iter2 != hapVerifyInfos.end(); iter2++) {
342 const HapVerifyInfo& hapVerifyInfo2 = *iter2;
343 if (hapVerifyInfo1.GetModuleName() == hapVerifyInfo2.GetModuleName() &&
344 !CheckDuplicatedIsValid(hapVerifyInfo1, hapVerifyInfo2)) {
345 ShowCheckTips(hapVerifyInfo1, hapVerifyInfo2, MODULE_NAME);
346 return false;
347 }
348 }
349 }
350 return true;
351 }
352
CheckDuplicatedIsValid(const HapVerifyInfo & hapVerifyInfo1,const HapVerifyInfo & hapVerifyInfo2)353 bool HapVerifyUtils::CheckDuplicatedIsValid(const HapVerifyInfo& hapVerifyInfo1, const HapVerifyInfo& hapVerifyInfo2)
354 {
355 if (Utils::CheckDisjoint(hapVerifyInfo1.GetDeviceTypes(), hapVerifyInfo2.GetDeviceTypes())) {
356 return true;
357 }
358 if (CheckDistroFilterDisjoint(hapVerifyInfo1.GetDistroFilter(), hapVerifyInfo2.GetDistroFilter())) {
359 return true;
360 }
361 return false;
362 }
363
CheckDistroFilterDisjoint(const DistroFilter & distroFilter1,const DistroFilter & distroFilter2)364 bool HapVerifyUtils::CheckDistroFilterDisjoint(const DistroFilter& distroFilter1, const DistroFilter& distroFilter2)
365 {
366 if (distroFilter1.IsEmpty() || distroFilter2.IsEmpty()) {
367 return false;
368 }
369 if (!distroFilter1.apiVersion.IsEmpty() && !distroFilter2.apiVersion.IsEmpty()) {
370 if (CheckPolicyValueDisjoint(distroFilter1.apiVersion, distroFilter2.apiVersion)) {
371 return true;
372 }
373 }
374 if (!distroFilter1.screenShape.IsEmpty() && !distroFilter2.screenShape.IsEmpty()) {
375 if (CheckPolicyValueDisjoint(distroFilter1.screenShape, distroFilter2.screenShape)) {
376 return true;
377 }
378 }
379 if (!distroFilter1.screenDensity.IsEmpty() && !distroFilter2.screenDensity.IsEmpty()) {
380 if (CheckPolicyValueDisjoint(distroFilter1.screenDensity, distroFilter2.screenDensity)) {
381 return true;
382 }
383 }
384 if (!distroFilter1.screenWindow.IsEmpty() && !distroFilter2.screenWindow.IsEmpty()) {
385 if (CheckPolicyValueDisjoint(distroFilter1.screenWindow, distroFilter2.screenWindow)) {
386 return true;
387 }
388 }
389 if (!distroFilter1.countryCode.IsEmpty() && !distroFilter2.countryCode.IsEmpty()) {
390 if (CheckPolicyValueDisjoint(distroFilter1.countryCode, distroFilter2.countryCode)) {
391 return true;
392 }
393 }
394 return false;
395 }
396
CheckPolicyValueDisjoint(const PolicyValue & policyValue1,const PolicyValue & policyValue2)397 bool HapVerifyUtils::CheckPolicyValueDisjoint(const PolicyValue& policyValue1, const PolicyValue& policyValue2)
398 {
399 if (policyValue1.policy == EXCLUDE && policyValue2.policy == INCLUDE) {
400 if (policyValue2.value.empty() || Utils::CheckContainsAll(policyValue1.value, policyValue2.value)) {
401 return true;
402 }
403 } else if (policyValue1.policy == INCLUDE && policyValue2.policy == INCLUDE) {
404 if (Utils::CheckDisjoint(policyValue1.value, policyValue2.value)) {
405 return true;
406 }
407 } else if (policyValue1.policy == INCLUDE && policyValue2.policy == EXCLUDE) {
408 if (policyValue1.value.empty() || Utils::CheckContainsAll(policyValue2.value, policyValue1.value)) {
409 return true;
410 }
411 } else if (policyValue1.policy == EXCLUDE && policyValue2.policy == EXCLUDE) {
412 LOGE("input policys are both exclude.");
413 return false;
414 } else {
415 LOGE("input policy is invalid.");
416 }
417 return false;
418 }
419
CheckPackageNameIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)420 bool HapVerifyUtils::CheckPackageNameIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
421 {
422 for (auto iter1 = hapVerifyInfos.begin(); iter1 != hapVerifyInfos.end(); iter1++) {
423 const HapVerifyInfo& hapVerifyInfo1 = *iter1;
424 if (hapVerifyInfo1.GetPackageName().empty()) {
425 continue;
426 }
427 for (auto iter2 = std::next(iter1); iter2 != hapVerifyInfos.end(); iter2++) {
428 const HapVerifyInfo& hapVerifyInfo2 = *iter2;
429 if (hapVerifyInfo1.GetPackageName() == hapVerifyInfo2.GetPackageName() &&
430 !CheckDuplicatedIsValid(hapVerifyInfo1, hapVerifyInfo2)) {
431 ShowCheckTips(hapVerifyInfo1, hapVerifyInfo2, PACKAGE_NAME);
432 return false;
433 }
434 }
435 }
436 return true;
437 }
438
CheckEntryIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)439 bool HapVerifyUtils::CheckEntryIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
440 {
441 std::list<HapVerifyInfo> entryHapVerifyInfos;
442 std::list<HapVerifyInfo> featureHapVerifyInfos;
443 for (auto& hapVerifyInfo : hapVerifyInfos) {
444 if (hapVerifyInfo.GetModuleType() == ENTRY) {
445 entryHapVerifyInfos.push_back(hapVerifyInfo);
446 } else if (hapVerifyInfo.GetModuleType() == FEATURE) {
447 featureHapVerifyInfos.push_back(hapVerifyInfo);
448 } else if (hapVerifyInfo.GetModuleType() != SHARED_LIBRARY) {
449 LOGW("Input wrong type module.");
450 }
451 }
452 if (hapVerifyInfos.empty() ||
453 (entryHapVerifyInfos.empty() && (*hapVerifyInfos.begin()).GetBundleType() != SHARED_LIBRARY)) {
454 LOGW("has no entry module.");
455 }
456 for (auto iter1 = entryHapVerifyInfos.begin(); iter1 != entryHapVerifyInfos.end(); iter1++) {
457 const HapVerifyInfo& entryHapVerifyInfo1 = *iter1;
458 for (auto iter2 = std::next(iter1); iter2 != entryHapVerifyInfos.end(); iter2++) {
459 const HapVerifyInfo& entryHapVerifyInfo2 = *iter2;
460 if (!CheckDuplicatedIsValid(entryHapVerifyInfo1, entryHapVerifyInfo2)) {
461 ShowCheckTips(entryHapVerifyInfo1, entryHapVerifyInfo2, ENTRY_NAME);
462 return false;
463 }
464 }
465 }
466 std::map<std::string, std::list<HapVerifyInfo>> deviceHaps;
467 ClassifyEntry(entryHapVerifyInfos, deviceHaps);
468 for (auto& hapVerifyInfo : featureHapVerifyInfos) {
469 if (!CheckFeature(hapVerifyInfo, deviceHaps)) {
470 LOGW("%s can not be covered by entry.", hapVerifyInfo.GetModuleName().c_str());
471 }
472 }
473 return true;
474 }
475
ClassifyEntry(const std::list<HapVerifyInfo> & entryHapVerifyInfos,std::map<std::string,std::list<HapVerifyInfo>> & deviceHaps)476 void HapVerifyUtils::ClassifyEntry(const std::list<HapVerifyInfo>& entryHapVerifyInfos,
477 std::map<std::string, std::list<HapVerifyInfo>>& deviceHaps)
478 {
479 for (auto& hapVerifyInfo : entryHapVerifyInfos) {
480 for (std::string device : hapVerifyInfo.GetDeviceTypes()) {
481 if (deviceHaps.count(device) > 0) {
482 deviceHaps[device].push_back(hapVerifyInfo);
483 } else {
484 std::list<HapVerifyInfo> hapVerifyInfos;
485 hapVerifyInfos.push_back(hapVerifyInfo);
486 deviceHaps.insert(std::make_pair(device, hapVerifyInfos));
487 }
488 }
489 }
490 }
491
CheckFeature(const HapVerifyInfo & featureHap,const std::map<std::string,std::list<HapVerifyInfo>> & deviceHap)492 bool HapVerifyUtils::CheckFeature(const HapVerifyInfo& featureHap,
493 const std::map<std::string, std::list<HapVerifyInfo>>& deviceHap)
494 {
495 for (auto& device : featureHap.GetDeviceTypes()) {
496 if (deviceHap.count(device) <= 0) {
497 LOGW("Warning: device %s has feature but has no entry.", device.c_str());
498 return false;
499 }
500 if (!CheckFeatureDistroFilter(featureHap, deviceHap.at(device))) {
501 LOGW("%s's distroFilter has not covered by entry.", featureHap.GetModuleName().c_str());
502 if (featureHap.GetDistroFilter().Dump() != EMPTY_STRING) {
503 LOGW("%s has %s.", featureHap.GetModuleName().c_str(),
504 featureHap.GetDistroFilter().Dump().c_str());
505 }
506 return false;
507 }
508 }
509 return true;
510 }
511
512
CheckFeatureDistroFilter(const HapVerifyInfo & featureHap,const std::list<HapVerifyInfo> & entryHaps)513 bool HapVerifyUtils::CheckFeatureDistroFilter(const HapVerifyInfo& featureHap,
514 const std::list<HapVerifyInfo>& entryHaps)
515 {
516 if (featureHap.GetDistroFilter().IsEmpty()) {
517 if (CheckApiVersionCovered(featureHap.GetDistroFilter().apiVersion, entryHaps) &&
518 CheckScreenShapeCovered(featureHap.GetDistroFilter().screenShape, entryHaps) &&
519 CheckScreenWindowCovered(featureHap.GetDistroFilter().screenWindow, entryHaps) &&
520 CheckScreenDensityCovered(featureHap.GetDistroFilter().screenDensity, entryHaps) &&
521 CheckCountryCodeCovered(featureHap.GetDistroFilter().countryCode, entryHaps)) {
522 return true;
523 } else {
524 return false;
525 }
526 }
527 if (!CheckApiVersionCovered(featureHap.GetDistroFilter().apiVersion, entryHaps)) {
528 LOGW("CheckApiVersionCovered failed, apiVersion is not covered.");
529 return false;
530 }
531 if (!CheckScreenShapeCovered(featureHap.GetDistroFilter().screenShape, entryHaps)) {
532 LOGW("CheckScreenShapeCovered failed, screenShape is not covered.");
533 return false;
534 }
535 if (!CheckScreenWindowCovered(featureHap.GetDistroFilter().screenWindow, entryHaps)) {
536 LOGW("CheckScreenWindowCovered failed, screenWindow is not covered.");
537 return false;
538 }
539 if (!CheckScreenDensityCovered(featureHap.GetDistroFilter().screenDensity, entryHaps)) {
540 LOGW("CheckScreenDensityCovered failed, screenDensity is not covered.");
541 return false;
542 }
543 if (!CheckCountryCodeCovered(featureHap.GetDistroFilter().countryCode, entryHaps)) {
544 LOGW("HapVerify::checkFeatureDistroFilter failed, countryCode is not covered.");
545 return false;
546 }
547 return true;
548 }
549
CheckApiVersionCovered(const ApiVersion & apiVersion,const std::list<HapVerifyInfo> & entryHaps)550 bool HapVerifyUtils::CheckApiVersionCovered(const ApiVersion& apiVersion, const std::list<HapVerifyInfo>& entryHaps)
551 {
552 std::set<std::string> includeSet;
553 std::set<std::string> excludeSet;
554 for (auto& hapVerifyInfo : entryHaps) {
555 if (hapVerifyInfo.GetDistroFilter().IsEmpty() || hapVerifyInfo.GetDistroFilter().apiVersion.IsEmpty()) {
556 LOGW("distro filter is empty or apiVersion is empty.");
557 return true;
558 }
559 if (hapVerifyInfo.GetDistroFilter().apiVersion.policy.empty()) {
560 LOGE("input none policy.");
561 return false;
562 }
563 if (hapVerifyInfo.GetDistroFilter().apiVersion.policy == INCLUDE) {
564 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().apiVersion.value, includeSet);
565 } else if (hapVerifyInfo.GetDistroFilter().apiVersion.policy == EXCLUDE) {
566 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().apiVersion.value, excludeSet);
567 } else {
568 LOGE("input policy is invalid.");
569 return false;
570 }
571 }
572 std::list<std::string> include(includeSet.begin(), includeSet.end());
573 std::list<std::string> exclude(excludeSet.begin(), excludeSet.end());
574 if (apiVersion.IsEmpty()) {
575 return CheckEntryPolicyValueCoverAll(include, exclude);
576 }
577 return CheckPolicyValueCovered(apiVersion, include, exclude);
578 }
579
CheckScreenShapeCovered(const ScreenShape & screenShape,const std::list<HapVerifyInfo> & entryHaps)580 bool HapVerifyUtils::CheckScreenShapeCovered(const ScreenShape& screenShape, const std::list<HapVerifyInfo>& entryHaps)
581 {
582 std::set<std::string> includeSet;
583 std::set<std::string> excludeSet;
584 for (HapVerifyInfo hapVerifyInfo : entryHaps) {
585 if (hapVerifyInfo.GetDistroFilter().IsEmpty() || hapVerifyInfo.GetDistroFilter().screenShape.IsEmpty()) {
586 LOGW("distro filter is empty or screenShape is empty.");
587 return true;
588 }
589 if (hapVerifyInfo.GetDistroFilter().screenShape.policy.empty()) {
590 LOGE("input none policy.");
591 return false;
592 }
593 if (hapVerifyInfo.GetDistroFilter().screenShape.policy == INCLUDE) {
594 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().screenShape.value, includeSet);
595 } else if (hapVerifyInfo.GetDistroFilter().screenShape.policy == EXCLUDE) {
596 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().screenShape.value, excludeSet);
597 } else {
598 LOGE("input policy is invalid.");
599 return false;
600 }
601 }
602 std::list<std::string> include(includeSet.begin(), includeSet.end());
603 std::list<std::string> exclude(excludeSet.begin(), excludeSet.end());
604 if (screenShape.IsEmpty()) {
605 return CheckEntryPolicyValueCoverAll(include, exclude);
606 }
607 return CheckPolicyValueCovered(screenShape, include, exclude);
608 }
609
CheckScreenWindowCovered(const ScreenWindow & screenWindow,const std::list<HapVerifyInfo> & entryHaps)610 bool HapVerifyUtils::CheckScreenWindowCovered(const ScreenWindow& screenWindow,
611 const std::list<HapVerifyInfo>& entryHaps)
612 {
613 std::set<std::string> includeSet;
614 std::set<std::string> excludeSet;
615 for (HapVerifyInfo hapVerifyInfo : entryHaps) {
616 if (hapVerifyInfo.GetDistroFilter().IsEmpty() || hapVerifyInfo.GetDistroFilter().screenWindow.IsEmpty()) {
617 LOGW("distro filter is empty or screenWindow is empty.");
618 return true;
619 }
620 if (hapVerifyInfo.GetDistroFilter().screenWindow.policy.empty()) {
621 LOGE("input none policy.");
622 return false;
623 }
624 if (hapVerifyInfo.GetDistroFilter().screenWindow.policy == INCLUDE) {
625 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().screenWindow.value, includeSet);
626 } else if (hapVerifyInfo.GetDistroFilter().screenWindow.policy == EXCLUDE) {
627 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().screenWindow.value, excludeSet);
628 } else {
629 LOGE("input policy is invalid.");
630 return false;
631 }
632 }
633 std::list<std::string> include(includeSet.begin(), includeSet.end());
634 std::list<std::string> exclude(excludeSet.begin(), excludeSet.end());
635 if (screenWindow.IsEmpty()) {
636 return CheckEntryPolicyValueCoverAll(include, exclude);
637 }
638 return CheckPolicyValueCovered(screenWindow, include, exclude);
639 }
640
CheckScreenDensityCovered(const ScreenDensity & screenDensity,const std::list<HapVerifyInfo> & entryHaps)641 bool HapVerifyUtils::CheckScreenDensityCovered(const ScreenDensity& screenDensity,
642 const std::list<HapVerifyInfo>& entryHaps)
643 {
644 std::set<std::string> includeSet;
645 std::set<std::string> excludeSet;
646 for (HapVerifyInfo hapVerifyInfo : entryHaps) {
647 if (hapVerifyInfo.GetDistroFilter().IsEmpty() || hapVerifyInfo.GetDistroFilter().screenDensity.IsEmpty()) {
648 LOGW("distro filter is empty or screenDensity is empty.");
649 return true;
650 }
651 if (hapVerifyInfo.GetDistroFilter().screenDensity.policy.empty()) {
652 LOGE("input none policy.");
653 return false;
654 }
655 if (hapVerifyInfo.GetDistroFilter().screenDensity.policy == INCLUDE) {
656 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().screenDensity.value, includeSet);
657 } else if (hapVerifyInfo.GetDistroFilter().screenDensity.policy == EXCLUDE) {
658 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().screenDensity.value, excludeSet);
659 } else {
660 LOGE("input policy is invalid.");
661 return false;
662 }
663 }
664 std::list<std::string> include(includeSet.begin(), includeSet.end());
665 std::list<std::string> exclude(excludeSet.begin(), excludeSet.end());
666 if (screenDensity.IsEmpty()) {
667 return CheckEntryPolicyValueCoverAll(include, exclude);
668 }
669 return CheckPolicyValueCovered(screenDensity, include, exclude);
670 }
671
CheckCountryCodeCovered(const CountryCode & countryCode,const std::list<HapVerifyInfo> & entryHaps)672 bool HapVerifyUtils::CheckCountryCodeCovered(const CountryCode& countryCode, const std::list<HapVerifyInfo>& entryHaps)
673 {
674 std::set<std::string> includeSet;
675 std::set<std::string> excludeSet;
676 for (HapVerifyInfo hapVerifyInfo : entryHaps) {
677 if (hapVerifyInfo.GetDistroFilter().IsEmpty() || hapVerifyInfo.GetDistroFilter().countryCode.IsEmpty()) {
678 LOGW("distro filter is empty or countryCode is empty.");
679 return true;
680 }
681 if (hapVerifyInfo.GetDistroFilter().countryCode.policy.empty()) {
682 LOGE("input none policy.");
683 return false;
684 }
685 if (hapVerifyInfo.GetDistroFilter().countryCode.policy == INCLUDE) {
686 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().countryCode.value, includeSet);
687 } else if (hapVerifyInfo.GetDistroFilter().countryCode.policy == EXCLUDE) {
688 Utils::CopyListToSet(hapVerifyInfo.GetDistroFilter().countryCode.value, excludeSet);
689 } else {
690 LOGE("input policy is invalid.");
691 return false;
692 }
693 }
694 std::list<std::string> include(includeSet.begin(), includeSet.end());
695 std::list<std::string> exclude(excludeSet.begin(), excludeSet.end());
696 if (countryCode.IsEmpty()) {
697 return CheckEntryPolicyValueCoverAll(include, exclude);
698 }
699 return CheckPolicyValueCovered(countryCode, include, exclude);
700 }
701
CheckEntryPolicyValueCoverAll(const std::list<std::string> & include,const std::list<std::string> & exclude)702 bool HapVerifyUtils::CheckEntryPolicyValueCoverAll(const std::list<std::string>& include,
703 const std::list<std::string>& exclude)
704 {
705 if (include.empty() && exclude.empty()) {
706 return true;
707 }
708 return !exclude.empty() && Utils::CheckContainsAll(include, exclude);
709 }
710
CheckPolicyValueCovered(const PolicyValue & policyValue,const std::list<std::string> & include,std::list<std::string> & exclude)711 bool HapVerifyUtils::CheckPolicyValueCovered(const PolicyValue& policyValue,
712 const std::list<std::string>& include, std::list<std::string>& exclude)
713 {
714 if (policyValue.policy == EXCLUDE) {
715 return CheckCoveredExcludePolicyValue(policyValue.value, include, exclude);
716 } else if (policyValue.policy == INCLUDE) {
717 return CheckCoveredIncludePolicyValue(policyValue.value, include, exclude);
718 }
719 return false;
720 }
721
722
CheckCoveredExcludePolicyValue(const std::list<std::string> & value,const std::list<std::string> & include,std::list<std::string> & exclude)723 bool HapVerifyUtils::CheckCoveredExcludePolicyValue(const std::list<std::string>& value,
724 const std::list<std::string>& include, std::list<std::string>& exclude)
725 {
726 if (include.empty()) {
727 return exclude.empty() || Utils::CheckContainsAll(value, exclude);
728 }
729 if (exclude.empty()) {
730 return false;
731 }
732 exclude.remove_if([&include](const std::string& value) {
733 return std::find(include.begin(), include.end(), value) != include.end();
734 });
735 return Utils::CheckContainsAll(value, exclude);
736 }
737
CheckCoveredIncludePolicyValue(const std::list<std::string> & value,const std::list<std::string> & include,std::list<std::string> & exclude)738 bool HapVerifyUtils::CheckCoveredIncludePolicyValue(const std::list<std::string>& value,
739 const std::list<std::string>& include, std::list<std::string>& exclude)
740 {
741 if (include.empty()) {
742 return exclude.empty() || Utils::CheckDisjoint(exclude, value);
743 }
744 if (exclude.empty()) {
745 return Utils::CheckContainsAll(include, value);
746 }
747 exclude.remove_if([&include](const std::string& value) {
748 return std::find(include.begin(), include.end(), value) != include.end();
749 });
750 return Utils::CheckDisjoint(exclude, value);
751 }
752
CheckDependencyIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)753 bool HapVerifyUtils::CheckDependencyIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
754 {
755 if (hapVerifyInfos.empty()) {
756 LOGE("input none hap.");
757 return false;
758 }
759 bool isInstallationFree = hapVerifyInfos.begin()->IsInstallationFree();
760 for (auto& hapVerifyInfo : hapVerifyInfos) {
761 if (isInstallationFree != hapVerifyInfo.IsInstallationFree()) {
762 LOGE("installationFree is different in input hap.");
763 return false;
764 }
765 }
766 for (auto& hapVerifyInfo : hapVerifyInfos) {
767 std::list<HapVerifyInfo> dependencyList;
768 dependencyList.push_back(hapVerifyInfo);
769 if (!DfsTraverseDependency(hapVerifyInfo, hapVerifyInfos, dependencyList)) {
770 return false;
771 }
772 dependencyList.pop_back();
773 }
774 return true;
775 }
776
DfsTraverseDependency(const HapVerifyInfo & hapVerifyInfo,const std::list<HapVerifyInfo> & hapVerifyInfos,std::list<HapVerifyInfo> & dependencyList)777 bool HapVerifyUtils::DfsTraverseDependency(const HapVerifyInfo& hapVerifyInfo,
778 const std::list<HapVerifyInfo>& hapVerifyInfos, std::list<HapVerifyInfo>& dependencyList)
779 {
780 if (CheckDependencyListCirculate(dependencyList)) {
781 return false;
782 }
783 for (const DependencyItem& dependency : hapVerifyInfo.GetDependencyItemList()) {
784 if (dependency.bundleName != hapVerifyInfo.GetBundleName()) {
785 continue;
786 }
787 if (!CheckDependencyInFileList(dependency, hapVerifyInfos)) {
788 LOGW("Dependent module %s missing, check the HSP-Path.", dependency.bundleName.c_str());
789 continue;
790 }
791 std::list<HapVerifyInfo> layerHapVerifyInfos;
792 GetLayerHapVerifyInfos(dependency.moduleName, hapVerifyInfo, hapVerifyInfos, layerHapVerifyInfos);
793 for (auto& layerHapVerifyInfo : layerHapVerifyInfos) {
794 if (layerHapVerifyInfo.GetModuleType() == FEATURE || layerHapVerifyInfo.GetModuleType() == ENTRY) {
795 LOGE("HAP or HSP cannot depend on HAP %s.", layerHapVerifyInfo.GetModuleName().c_str());
796 return false;
797 }
798 dependencyList.push_back(layerHapVerifyInfo);
799 if (!DfsTraverseDependency(layerHapVerifyInfo, hapVerifyInfos, dependencyList)) {
800 return false;
801 }
802 dependencyList.pop_back();
803 }
804 }
805 return true;
806 }
807
CheckDependencyListCirculate(const std::list<HapVerifyInfo> & dependencyList)808 bool HapVerifyUtils::CheckDependencyListCirculate(const std::list<HapVerifyInfo>& dependencyList)
809 {
810 for (auto iter1 = dependencyList.begin(); iter1 != dependencyList.end(); iter1++) {
811 const HapVerifyInfo& dependency1 = *iter1;
812 for (auto iter2 = std::next(iter1); iter2 != dependencyList.end(); iter2++) {
813 const HapVerifyInfo& dependency2 = *iter2;
814 if (IsSameHapVerifyInfo(dependency1, dependency2)) {
815 std::list<std::string> moduleNames;
816 GetHapVerifyInfosNames(dependencyList, moduleNames);
817 LOGE("circular dependency, dependencyList is %s.", Utils::ListToString(moduleNames).c_str());
818 return true;
819 }
820 }
821 }
822 return false;
823 }
824
IsSameHapVerifyInfo(const HapVerifyInfo & hapVerifyInfo1,const HapVerifyInfo & hapVerifyInfo2)825 bool HapVerifyUtils::IsSameHapVerifyInfo(const HapVerifyInfo& hapVerifyInfo1, const HapVerifyInfo& hapVerifyInfo2)
826 {
827 if (hapVerifyInfo1.GetModuleName() != hapVerifyInfo2.GetModuleName()) {
828 return false;
829 }
830 return CheckModuleJoint(hapVerifyInfo1, hapVerifyInfo2);
831 }
832
CheckModuleJoint(const HapVerifyInfo & infoLeft,const HapVerifyInfo & infoRight)833 bool HapVerifyUtils::CheckModuleJoint(const HapVerifyInfo& infoLeft, const HapVerifyInfo& infoRight)
834 {
835 return !CheckDuplicatedIsValid(infoLeft, infoRight);
836 }
837
GetHapVerifyInfosNames(const std::list<HapVerifyInfo> & hapVerifyInfos,std::list<std::string> & moduleNames)838 void HapVerifyUtils::GetHapVerifyInfosNames(const std::list<HapVerifyInfo>& hapVerifyInfos,
839 std::list<std::string>& moduleNames)
840 {
841 for (auto& hapVerifyInfo : hapVerifyInfos) {
842 moduleNames.push_back(hapVerifyInfo.GetModuleName());
843 }
844 }
845
CheckDependencyInFileList(const DependencyItem & dependencyItem,const std::list<HapVerifyInfo> & hapVerifyInfos)846 bool HapVerifyUtils::CheckDependencyInFileList(const DependencyItem& dependencyItem,
847 const std::list<HapVerifyInfo>& hapVerifyInfos)
848 {
849 for (auto& hapVerifyInfo : hapVerifyInfos) {
850 if (dependencyItem.moduleName == hapVerifyInfo.GetModuleName() &&
851 dependencyItem.bundleName == hapVerifyInfo.GetBundleName()) {
852 return true;
853 }
854 }
855 return false;
856 }
857
GetLayerHapVerifyInfos(const std::string & moduleName,const HapVerifyInfo & hapVerifyInfo,const std::list<HapVerifyInfo> & hapVerifyInfos,std::list<HapVerifyInfo> & layerHapVerifyInfos)858 void HapVerifyUtils::GetLayerHapVerifyInfos(const std::string& moduleName, const HapVerifyInfo& hapVerifyInfo,
859 const std::list<HapVerifyInfo>& hapVerifyInfos, std::list<HapVerifyInfo>& layerHapVerifyInfos)
860 {
861 for (auto& hapVerifyInfo : hapVerifyInfos) {
862 if (hapVerifyInfo.GetModuleName() == moduleName && CheckModuleJoint(hapVerifyInfo, hapVerifyInfo)) {
863 layerHapVerifyInfos.push_back(hapVerifyInfo);
864 }
865 }
866 }
867
CheckAtomicServiceIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)868 bool HapVerifyUtils::CheckAtomicServiceIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
869 {
870 if (hapVerifyInfos.empty()) {
871 LOGE("hapVerifyInfos is empty!");
872 return false;
873 }
874 if (hapVerifyInfos.begin()->GetBundleType() != ATOMIC_SERVICE) {
875 return true;
876 }
877 if (!hapVerifyInfos.begin()->IsStageModule()) {
878 return true;
879 }
880 std::map<std::string, std::list<HapVerifyInfo>> deviceInfosMap;
881 if (!GetDeviceHapVerifyInfoMap(hapVerifyInfos, deviceInfosMap)) {
882 LOGE("GetDeviceHapVerifyInfoMap failed!");
883 return false;
884 }
885 std::map<std::string, std::list<HapVerifyInfo>>::iterator iter;
886 for (iter = deviceInfosMap.begin(); iter != deviceInfosMap.end(); iter++) {
887 const std::string& deviceType = iter->first;
888 const std::list<HapVerifyInfo>& deviceInfos = iter->second;
889 if (!CheckAtomicServicePreloadsIsValid(deviceInfos)) {
890 LOGE("CheckAtomicServicePreloadsIsValid failed on device %s.", deviceType.c_str());
891 return false;
892 }
893 }
894 return true;
895 }
896
GetDeviceHapVerifyInfoMap(const std::list<HapVerifyInfo> & hapVerifyInfos,std::map<std::string,std::list<HapVerifyInfo>> & deviceInfosMap)897 bool HapVerifyUtils::GetDeviceHapVerifyInfoMap(const std::list<HapVerifyInfo>& hapVerifyInfos,
898 std::map<std::string, std::list<HapVerifyInfo>>& deviceInfosMap)
899 {
900 if (hapVerifyInfos.empty()) {
901 LOGE("hapVerifyInfos is empty!");
902 return false;
903 }
904 for (auto& hapVerifyInfo : hapVerifyInfos) {
905 const std::list<std::string>& deviceTypes = hapVerifyInfo.GetDeviceTypes();
906 for (auto& deviceType : deviceTypes) {
907 if (deviceInfosMap.count(deviceType) <= 0) {
908 std::list<HapVerifyInfo> deviceInfos;
909 deviceInfos.push_back(hapVerifyInfo);
910 deviceInfosMap.insert(std::make_pair(deviceType, deviceInfos));
911 } else {
912 deviceInfosMap[deviceType].push_back(hapVerifyInfo);
913 }
914 }
915 }
916 return true;
917 }
918
CheckAtomicServicePreloadsIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)919 bool HapVerifyUtils::CheckAtomicServicePreloadsIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
920 {
921 if (hapVerifyInfos.empty()) {
922 LOGE("hapVerifyInfos is empty!");
923 return false;
924 }
925 std::list<std::string> moduleNames;
926 GetHapVerifyInfosNames(hapVerifyInfos, moduleNames);
927 // check preload module is existed and not self
928 for (auto& hapVerifyInfo : hapVerifyInfos) {
929 std::list<std::string> preloadModuleNames;
930 const std::list<PreloadItem>& preloadItems = hapVerifyInfo.GetPreloadItems();
931 for (PreloadItem preloadItem : preloadItems) {
932 if (Utils::CheckListContain(preloadModuleNames, preloadItem.moduleName)) {
933 LOGE("preloads config a duplicate module %s in %s.",
934 preloadItem.moduleName.c_str(), hapVerifyInfo.GetModuleName().c_str());
935 return false;
936 }
937 preloadModuleNames.push_back(preloadItem.moduleName);
938 if (!Utils::CheckListContain(moduleNames, preloadItem.moduleName)) {
939 LOGE("preloads config a invalid module %s in %s.",
940 preloadItem.moduleName.c_str(), hapVerifyInfo.GetModuleName().c_str());
941 return false;
942 }
943 if (preloadItem.moduleName == hapVerifyInfo.GetModuleName()) {
944 LOGE("can not preload self, %s preload self.", hapVerifyInfo.GetModuleName().c_str());
945 return false;
946 }
947 }
948 }
949 // check feature preload is valid
950 std::map<std::string, std::string> moduleNameWithType;
951 for (HapVerifyInfo hapVerifyInfo : hapVerifyInfos) {
952 moduleNameWithType.insert(std::make_pair(hapVerifyInfo.GetModuleName(), hapVerifyInfo.GetModuleType()));
953 }
954 for (HapVerifyInfo hapVerifyInfo : hapVerifyInfos) {
955 const std::list<PreloadItem>& preloadItems = hapVerifyInfo.GetPreloadItems();
956 for (auto& preloadItem : preloadItems) {
957 if ((moduleNameWithType.count(preloadItem.moduleName) > 0) &&
958 (moduleNameWithType[preloadItem.moduleName] == ENTRY ||
959 moduleNameWithType[preloadItem.moduleName] == HAR)) {
960 LOGE("feature or shared can not preload entry or har, %s preloads a %s module.",
961 hapVerifyInfo.GetModuleName().c_str(), moduleNameWithType[preloadItem.moduleName].c_str());
962 return false;
963 }
964 }
965 }
966 return true;
967 }
968
CheckFileSizeIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)969 bool HapVerifyUtils::CheckFileSizeIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
970 {
971 if (hapVerifyInfos.empty()) {
972 LOGE("hapVerifyInfos is empty!");
973 return false;
974 }
975 // check single file length
976 int32_t entryLimit = hapVerifyInfos.begin()->GetEntrySizeLimit();
977 int32_t notEntryLimit = hapVerifyInfos.begin()->GetNotEntrySizeLimit();
978 for (HapVerifyInfo hapVerifyInfo : hapVerifyInfos) {
979 if (hapVerifyInfo.GetModuleType() == ENTRY &&
980 entryLimit != 0 &&
981 (hapVerifyInfo.GetFileLength() >= entryLimit * FILE_LENGTH_1KB)) {
982 LOGE("module %s's size is %.2f KB, which is overlarge than %d KB.",
983 hapVerifyInfo.GetModuleName().c_str(),
984 Utils::GetCeilFileSize(hapVerifyInfo.GetFileLength(), entryLimit), entryLimit);
985 return false;
986 }
987 if (hapVerifyInfo.GetModuleType() != ENTRY &&
988 notEntryLimit != 0 &&
989 (hapVerifyInfo.GetFileLength() >= notEntryLimit * FILE_LENGTH_1KB)) {
990 LOGE("module %s's size is %.2f KB, which is overlarge than %d KB.",
991 hapVerifyInfo.GetModuleName().c_str(),
992 Utils::GetCeilFileSize(hapVerifyInfo.GetFileLength(), notEntryLimit),
993 notEntryLimit);
994 return false;
995 }
996 }
997
998 std::map<std::string, std::list<HapVerifyInfo>> deviceInfosMap;
999 if (!GetDeviceHapVerifyInfoMap(hapVerifyInfos, deviceInfosMap)) {
1000 LOGE("HapVerifyUtils::CheckFileSizeIsValid GetDeviceHapVerifyInfoMap failed!");
1001 return false;
1002 }
1003 std::map<std::string, std::list<HapVerifyInfo>>::iterator iter;
1004 for (iter = deviceInfosMap.begin(); iter != deviceInfosMap.end(); iter++) {
1005 const std::string& deviceType = iter->first;
1006 const std::list<HapVerifyInfo>& deviceInfos = iter->second;
1007 if (!CheckAtomicServiceModuleSize(deviceInfos)) {
1008 LOGE("checkAtomicServiceModuleSize failed on device %s.", deviceType.c_str());
1009 return false;
1010 }
1011 }
1012 return true;
1013 }
1014
CheckAtomicServiceModuleSize(const std::list<HapVerifyInfo> & hapVerifyInfos)1015 bool HapVerifyUtils::CheckAtomicServiceModuleSize(const std::list<HapVerifyInfo>& hapVerifyInfos)
1016 {
1017 if (hapVerifyInfos.empty()) {
1018 LOGE("hapVerifyInfos is empty!");
1019 return false;
1020 }
1021 int32_t entryLimit = hapVerifyInfos.begin()->GetEntrySizeLimit();
1022 int32_t notEntryLimit = hapVerifyInfos.begin()->GetNotEntrySizeLimit();
1023 for (auto& hapVerifyInfo : hapVerifyInfos) {
1024 std::list<std::string> dependencies;
1025 GetModuleDependency(hapVerifyInfo, hapVerifyInfos, dependencies);
1026 std::list<HapVerifyInfo> dependenciesInfos;
1027 for (auto& module : dependencies) {
1028 const HapVerifyInfo *info = FindAtomicServiceHapVerifyInfo(module, hapVerifyInfos);
1029 if (info != nullptr) {
1030 dependenciesInfos.push_back(*info);
1031 }
1032 }
1033 long fileSize = hapVerifyInfo.GetFileLength();
1034 for (auto& dependency : dependenciesInfos) {
1035 fileSize += dependency.GetFileLength();
1036 }
1037 if (hapVerifyInfo.GetModuleType() == ENTRY &&
1038 entryLimit != 0 &&
1039 (fileSize >= entryLimit * FILE_LENGTH_1KB)) {
1040 LOGE("module %s and it's dependencies size is %.2f KB, which is overlarge than %d KB.",
1041 hapVerifyInfo.GetModuleName().c_str(),
1042 Utils::GetCeilFileSize(fileSize, entryLimit),
1043 entryLimit);
1044 return false;
1045 }
1046 if (hapVerifyInfo.GetModuleType() != ENTRY &&
1047 notEntryLimit != 0 &&
1048 (fileSize >= notEntryLimit * FILE_LENGTH_1KB)) {
1049 LOGE("module %s and it's dependencies size is %.2f KB, which is overlarge than %d KB.",
1050 hapVerifyInfo.GetModuleName().c_str(),
1051 Utils::GetCeilFileSize(fileSize, notEntryLimit),
1052 notEntryLimit);
1053 return false;
1054 }
1055 }
1056 return true;
1057 }
1058
GetModuleDependency(const HapVerifyInfo & hapVerifyInfo,const std::list<HapVerifyInfo> & hapVerifyInfoList,std::list<std::string> & moduleDependency)1059 void HapVerifyUtils::GetModuleDependency(const HapVerifyInfo& hapVerifyInfo,
1060 const std::list<HapVerifyInfo>& hapVerifyInfoList, std::list<std::string>& moduleDependency)
1061 {
1062 moduleDependency.insert(moduleDependency.end(),
1063 hapVerifyInfo.GetDependencies().begin(), hapVerifyInfo.GetDependencies().end());
1064 const std::list<std::string>& dependencyItems = hapVerifyInfo.GetDependencies();
1065 for (auto& dependencyItem : dependencyItems) {
1066 const HapVerifyInfo *dependencyHapVerifyInfo =
1067 FindAtomicServiceHapVerifyInfo(dependencyItem, hapVerifyInfoList);
1068 if (dependencyHapVerifyInfo == nullptr) {
1069 continue;
1070 }
1071 std::list<std::string> childDependencies;
1072 GetModuleDependency(*dependencyHapVerifyInfo, hapVerifyInfoList, childDependencies);
1073 for (auto& childDependency : childDependencies) {
1074 if (std::find(moduleDependency.begin(), moduleDependency.end(), childDependency) ==
1075 moduleDependency.end()) {
1076 moduleDependency.push_back(childDependency);
1077 }
1078 }
1079 }
1080 }
1081
FindAtomicServiceHapVerifyInfo(const std::string & moduleName,const std::list<HapVerifyInfo> & hapVerifyInfos)1082 const HapVerifyInfo* HapVerifyUtils::FindAtomicServiceHapVerifyInfo(const std::string& moduleName,
1083 const std::list<HapVerifyInfo>& hapVerifyInfos)
1084 {
1085 for (auto& hapVerifyInfo : hapVerifyInfos) {
1086 if (hapVerifyInfo.GetModuleName() == moduleName) {
1087 return &hapVerifyInfo;
1088 }
1089 }
1090 return nullptr;
1091 }
1092
CheckAbilityNameIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)1093 bool HapVerifyUtils::CheckAbilityNameIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
1094 {
1095 for (auto& hapVerifyInfo : hapVerifyInfos) {
1096 long noDuplicatedCount = Utils::GetListDistinctCount(hapVerifyInfo.GetAbilityNames());
1097 if (noDuplicatedCount != (long)hapVerifyInfo.GetAbilityNames().size()) {
1098 LOGW("%s ability duplicated, please rename ability name.", hapVerifyInfo.GetModuleName().c_str());
1099 return false;
1100 }
1101 }
1102 for (auto iter1 = hapVerifyInfos.begin(); iter1 != hapVerifyInfos.end(); iter1++) {
1103 const HapVerifyInfo& hapVerifyInfo1 = *iter1;
1104 if (hapVerifyInfo1.GetAbilityNames().empty()) {
1105 continue;
1106 }
1107 for (auto iter2 = std::next(iter1); iter2 != hapVerifyInfos.end(); iter2++) {
1108 const HapVerifyInfo& hapVerifyInfo2 = *iter2;
1109 if (!Utils::CheckDisjoint(hapVerifyInfo1.GetAbilityNames(), hapVerifyInfo2.GetAbilityNames()) &&
1110 !CheckDuplicatedIsValid(hapVerifyInfo1, hapVerifyInfo2)) {
1111 LOGW("Module: (%s) and Module: (%s) have the same ability name.",
1112 hapVerifyInfo1.GetModuleName().c_str(),
1113 hapVerifyInfo2.GetModuleName().c_str());
1114 LOGW("Module: %s has ability %s.",
1115 hapVerifyInfo1.GetModuleName().c_str(),
1116 Utils::ListToString(hapVerifyInfo1.GetAbilityNames()).c_str());
1117 LOGW("Module: %s has ability %s.",
1118 hapVerifyInfo2.GetModuleName().c_str(),
1119 Utils::ListToString(hapVerifyInfo2.GetAbilityNames()).c_str());
1120 LOGW("Solution: Make sure ability name is valid and unique.");
1121 LOGW("Reference: %s.", REFERENCE_LINK.c_str());
1122 return false;
1123 }
1124 }
1125 }
1126 return true;
1127 }
1128
CheckTargetModuleNameIsExisted(const std::list<HapVerifyInfo> & hapVerifyInfos)1129 bool HapVerifyUtils::CheckTargetModuleNameIsExisted(const std::list<HapVerifyInfo>& hapVerifyInfos)
1130 {
1131 std::list<HapVerifyInfo> internalOverlayHaps;
1132 std::list<HapVerifyInfo> nonOverlayHaps;
1133 std::list<std::string> targetModules;
1134 std::list<std::string> modules;
1135 for (auto& hapVerifyInfo : hapVerifyInfos) {
1136 if (!hapVerifyInfo.GetTargetBundleName().empty()) {
1137 return true;
1138 }
1139 if (!hapVerifyInfo.GetTargetModuleName().empty()) {
1140 internalOverlayHaps.push_back(hapVerifyInfo);
1141 targetModules.push_back(hapVerifyInfo.GetTargetModuleName());
1142 continue;
1143 }
1144 nonOverlayHaps.push_back(hapVerifyInfo);
1145 if (hapVerifyInfo.GetModuleType() != SHARED_LIBRARY) {
1146 modules.push_back(hapVerifyInfo.GetModuleName());
1147 }
1148 }
1149 if (internalOverlayHaps.empty()) {
1150 return true;
1151 }
1152 if (nonOverlayHaps.empty()) {
1153 LOGE("target modules are needed to pack with overlay module.");
1154 return false;
1155 }
1156 if (!Utils::CheckContainsAll(modules, targetModules)) {
1157 LOGE("target modules are needed to pack with overlay module.");
1158 return false;
1159 }
1160 return true;
1161 }
1162
CheckCompileSdkIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)1163 bool HapVerifyUtils::CheckCompileSdkIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
1164 {
1165 if (hapVerifyInfos.empty()) {
1166 LOGE("hapVerifyInfos is empty!");
1167 return false;
1168 }
1169 std::string compileSdkVersion = hapVerifyInfos.begin()->GetCompileSdkVersion();
1170 std::string compileSdkType = hapVerifyInfos.begin()->GetCompileSdkType();
1171 for (auto& hapVerifyInfo : hapVerifyInfos) {
1172 if (hapVerifyInfo.GetCompileSdkType() != compileSdkType) {
1173 LOGE("compile sdk type is not same.");
1174 return false;
1175 }
1176 if (hapVerifyInfo.GetCompileSdkVersion() != compileSdkVersion) {
1177 LOGE("compile sdk version is not same.");
1178 return false;
1179 }
1180 }
1181 return true;
1182 }
1183
CheckProxyDataUriIsUnique(const std::list<HapVerifyInfo> & hapVerifyInfos)1184 bool HapVerifyUtils::CheckProxyDataUriIsUnique(const std::list<HapVerifyInfo>& hapVerifyInfos)
1185 {
1186 if (hapVerifyInfos.empty()) {
1187 LOGE("hapVerifyInfos is empty!");
1188 return false;
1189 }
1190 std::list<std::string> uris;
1191 for (auto& hapVerifyInfo : hapVerifyInfos) {
1192 for (auto& uri : hapVerifyInfo.GetProxyDataUris()) {
1193 if (std::find(uris.begin(), uris.end(), uri) != uris.end()) {
1194 LOGE("uri %s in proxy data is duplicated", uri.c_str());
1195 LOGE("Solutions: > Check if the uri in proxyData is unique in different modules.");
1196 return false;
1197 } else {
1198 uris.push_back(uri);
1199 }
1200 }
1201 }
1202 return true;
1203 }
1204
CheckContinueTypeIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)1205 bool HapVerifyUtils::CheckContinueTypeIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
1206 {
1207 for (auto& hapVerifyInfo : hapVerifyInfos) {
1208 if (!CheckContinueTypeIsValid(hapVerifyInfo)) {
1209 LOGE("CheckContinueTypeIsValid failed!");
1210 return false;
1211 }
1212 }
1213 for (auto iter1 = hapVerifyInfos.begin(); iter1 != hapVerifyInfos.end(); iter1++) {
1214 for (auto iter2 = std::next(iter1); iter2 != hapVerifyInfos.end(); iter2++) {
1215 if (!CheckContinueTypeIsValid(*iter1, *iter2)) {
1216 LOGE("CheckContinueTypeIsValid failed!");
1217 return false;
1218 }
1219 }
1220 }
1221 return true;
1222 }
1223
CheckContinueTypeIsValid(const HapVerifyInfo & hapVerifyInfo)1224 bool HapVerifyUtils::CheckContinueTypeIsValid(const HapVerifyInfo& hapVerifyInfo)
1225 {
1226 const std::list<std::string>& abilityNames = hapVerifyInfo.GetAbilityNames();
1227 if (abilityNames.size() < TWO) {
1228 return true;
1229 }
1230 for (auto iter1 = abilityNames.begin(); iter1 != abilityNames.end(); iter1++) {
1231 std::list<std::string> typeList1;
1232 if (hapVerifyInfo.GetContinueTypeMap().find(*iter1) != hapVerifyInfo.GetContinueTypeMap().end()) {
1233 typeList1 = hapVerifyInfo.GetContinueTypeMap().at(*iter1);
1234 }
1235 if (typeList1.empty()) {
1236 continue;
1237 }
1238 for (auto iter2 = std::next(iter1); iter2 != abilityNames.end(); iter2++) {
1239 std::list<std::string> typeList2;
1240 if (hapVerifyInfo.GetContinueTypeMap().find(*iter2) != hapVerifyInfo.GetContinueTypeMap().end()) {
1241 typeList2 = hapVerifyInfo.GetContinueTypeMap().at(*iter2);
1242 }
1243 if (typeList2.empty()) {
1244 continue;
1245 }
1246 if (!Utils::CheckDisjoint(typeList1, typeList2)) {
1247 LOGE("Module: (%s), Ability: (%s) and Ability: (%s) have same continueType.",
1248 hapVerifyInfo.GetModuleName().c_str(), (*iter1).c_str(), (*iter2).c_str());
1249 LOGE("Ability: (%s) have continueType: %s", (*iter1).c_str(),
1250 Utils::ListToString(typeList1).c_str());
1251 LOGE("Another Ability: (%s) have continueType: %s", (*iter1).c_str(),
1252 Utils::ListToString(typeList2).c_str());
1253 return false;
1254 }
1255 }
1256 }
1257 return true;
1258 }
1259
CheckContinueTypeIsValid(const HapVerifyInfo & hapVerifyInfo1,const HapVerifyInfo & hapVerifyInfo2)1260 bool HapVerifyUtils::CheckContinueTypeIsValid(const HapVerifyInfo& hapVerifyInfo1, const HapVerifyInfo& hapVerifyInfo2)
1261 {
1262 if (Utils::CheckDisjoint(hapVerifyInfo1.GetDeviceTypes(), hapVerifyInfo2.GetDeviceTypes())) {
1263 return true;
1264 }
1265 const std::map<std::string, std::list<std::string>>& typeMap1 = hapVerifyInfo1.GetContinueTypeMap();
1266 const std::map<std::string, std::list<std::string>>& typeMap2 = hapVerifyInfo2.GetContinueTypeMap();
1267 std::list<std::string> typeList1;
1268 std::list<std::string> typeList2;
1269 for (auto iter = typeMap1.begin(); iter != typeMap1.end(); iter++) {
1270 typeList1.insert(typeList1.end(), iter->second.begin(), iter->second.end());
1271 }
1272 for (auto iter = typeMap2.begin(); iter != typeMap2.end(); iter++) {
1273 typeList2.insert(typeList2.end(), iter->second.begin(), iter->second.end());
1274 }
1275 if (!Utils::CheckDisjoint(typeList1, typeList2)) {
1276 LOGE("Module: (%s) and Module: (%s) have same deviceType and continueType.",
1277 hapVerifyInfo1.GetModuleName().c_str(), hapVerifyInfo2.GetModuleName().c_str());
1278 LOGE("Module: (%s) have deviceType: %s and continueType: %s",
1279 hapVerifyInfo1.GetModuleName().c_str(),
1280 Utils::ListToString(hapVerifyInfo1.GetDeviceTypes()).c_str(),
1281 Utils::ListToString(typeList1).c_str());
1282 LOGE("Another Module: (%s) have deviceType: %s and continueType: %s",
1283 hapVerifyInfo2.GetModuleName().c_str(),
1284 Utils::ListToString(hapVerifyInfo2.GetDeviceTypes()).c_str(),
1285 Utils::ListToString(typeList2).c_str());
1286 return false;
1287 }
1288 return true;
1289 }
1290
1291 // java : Compressor::checkSharedAppIsValid / HapVerify::checkSharedApppIsValid
CheckSharedAppIsValid(const std::list<HapVerifyInfo> & hapVerifyInfos)1292 bool HapVerifyUtils::CheckSharedAppIsValid(const std::list<HapVerifyInfo>& hapVerifyInfos)
1293 {
1294 if (hapVerifyInfos.empty()) {
1295 LOGE("hapVerifyInfos is empty!");
1296 return false;
1297 }
1298 std::string moduleName = hapVerifyInfos.begin()->GetModuleName();
1299 for (auto& hapVerifyInfo : hapVerifyInfos) {
1300 if (hapVerifyInfo.GetModuleName() != moduleName) {
1301 LOGE("moduleName is not same");
1302 return false;
1303 }
1304 if (!hapVerifyInfo.GetDependencyItemList().empty()) {
1305 LOGE("dependencyItems is empty");
1306 return false;
1307 }
1308 if (hapVerifyInfo.GetModuleType() != TYPE_SHARED) {
1309 LOGE("moduleType is not %s", TYPE_SHARED.c_str());
1310 return false;
1311 }
1312 }
1313 for (auto iter1 = hapVerifyInfos.begin(); iter1 != hapVerifyInfos.end(); iter1++) {
1314 for (auto iter2 = std::next(iter1); iter2 != hapVerifyInfos.end(); iter2++) {
1315 if (!CheckDuplicatedIsValid(*iter1, *iter2)) {
1316 LOGE("CheckDuplicatedIsValid failed!");
1317 return false;
1318 }
1319 }
1320 }
1321 return true;
1322 }
1323 } // namespace AppPackingTool
1324 } // namespace OHOS
1325