• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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