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