• 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_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