• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "parse_util.h"
17 
18 #include <cinttypes>
19 #include <dlfcn.h>
20 #include <fstream>
21 #include <memory>
22 #include <sstream>
23 #include <vector>
24 
25 #include "datetime_ex.h"
26 #include "hisysevent_adapter.h"
27 #include "hitrace_meter.h"
28 #include "sam_log.h"
29 #include "string_ex.h"
30 
31 namespace OHOS {
32 using std::string;
33 
34 namespace {
35 constexpr const char* EVENT_TYPE = "eventId";
36 constexpr const char* EVENT_NAME = "name";
37 constexpr const char* EVENT_VALUE = "value";
38 constexpr const char* SA_TAG_SYSTEM_ABILITY = "systemability";
39 constexpr const char* SA_TAG_PROCESS = "process";
40 constexpr const char* SA_TAG_LIB_PATH = "libpath";
41 constexpr const char* SA_TAG_NAME = "name";
42 constexpr const char* SA_TAG_DEPEND = "depend";
43 constexpr const char* SA_TAG_DEPEND_TIMEOUT = "depend-time-out";
44 constexpr const char* SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY = "depend_time_out";
45 constexpr const char* SA_TAG_RUN_ON_CREATE = "run-on-create";
46 constexpr const char* SA_TAG_AUTO_RESTART = "auto-restart";
47 constexpr const char* SA_TAG_DISTRIBUTED = "distributed";
48 constexpr const char* SA_TAG_DUMP_LEVEL = "dump-level";
49 constexpr const char* SA_TAG_CAPABILITY = "capability";
50 constexpr const char* SA_TAG_PERMISSION = "permission";
51 constexpr const char* SA_TAG_BOOT_PHASE = "bootphase";
52 constexpr const char* SA_TAG_SAID = "said";
53 constexpr const char* SA_TAG_START_ON_DEMAND = "start-on-demand";
54 constexpr const char* SA_TAG_STOP_ON_DEMAND = "stop-on-demand";
55 constexpr const char* SA_TAG_ALLOW_UPDATE = "allow-update";
56 constexpr const char* SA_TAG_RECYCLE_DELAYTIME = "recycle-delaytime";
57 constexpr const char* SA_TAG_DEVICE_ON_LINE = "deviceonline";
58 constexpr const char* SA_TAG_SETTING_SWITCH = "settingswitch";
59 constexpr const char* SA_TAG_COMMON_EVENT = "commonevent";
60 constexpr const char* SA_TAG_PARAM = "param";
61 constexpr const char* SA_TAG_TIEMD_EVENT = "timedevent";
62 constexpr int32_t MAX_JSON_OBJECT_SIZE = 50 * 1024;
63 constexpr int32_t MAX_JSON_STRING_LENGTH = 128;
64 constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000001;
65 constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
66 const string BOOT_START_PHASE = "BootStartPhase";
67 const string CORE_START_PHASE = "CoreStartPhase";
68 
69 enum {
70     BOOT_START = 1,
71     CORE_START = 2,
72     OTHER_START = 3,
73 };
74 
ParseLibPath(const string & libPath,string & fileName,string & libDir)75 void ParseLibPath(const string& libPath, string& fileName, string& libDir)
76 {
77     std::vector<string> libPathVec;
78     SplitStr(libPath, "/", libPathVec);
79     if ((libPathVec.size() > 0)) {
80         int fileNameIndex = static_cast<int>(libPathVec.size()) - 1;
81         fileName = libPathVec[fileNameIndex];
82         int libDirIndex = fileNameIndex - 1;
83         if (libDirIndex >= 0) {
84             libDir = libPathVec[libDirIndex];
85         }
86     }
87     if (libDir.empty()) {
88 #ifdef __aarch64__
89         libDir = "lib64";
90 #else
91         libDir = "lib";
92 #endif
93     }
94 }
95 }
96 
~ParseUtil()97 ParseUtil::~ParseUtil()
98 {
99     ClearResource();
100 }
101 
CloseHandle(SaProfile & saProfile)102 void ParseUtil::CloseHandle(SaProfile& saProfile)
103 {
104     if (saProfile.handle == nullptr) {
105         return;
106     }
107     int32_t ret = dlclose(saProfile.handle);
108     if (ret) {
109         HILOGW("close handle failed with errno:%{public}d!", errno);
110     }
111     saProfile.handle = nullptr;
112 }
113 
CloseSo()114 void ParseUtil::CloseSo()
115 {
116     for (auto& saProfile : saProfiles_) {
117         CloseHandle(saProfile);
118     }
119 }
120 
CloseSo(int32_t systemAbilityId)121 void ParseUtil::CloseSo(int32_t systemAbilityId)
122 {
123     for (auto& saProfile : saProfiles_) {
124         if (saProfile.saId == systemAbilityId) {
125             CloseHandle(saProfile);
126             break;
127         }
128     }
129 }
130 
ClearResource()131 void ParseUtil::ClearResource()
132 {
133     CloseSo();
134     saProfiles_.clear();
135 }
136 
SetUpdateList(const std::vector<std::string> & updateVec)137 void ParseUtil::SetUpdateList(const std::vector<std::string>& updateVec)
138 {
139     updateVec_ = updateVec;
140 }
141 
OpenSo(uint32_t bootPhase)142 void ParseUtil::OpenSo(uint32_t bootPhase)
143 {
144     for (auto& saProfile : saProfiles_) {
145         if (saProfile.runOnCreate && saProfile.bootPhase == bootPhase) {
146             OpenSo(saProfile);
147         }
148     }
149 }
150 
IsUpdateSA(const std::string & saId)151 bool ParseUtil::IsUpdateSA(const std::string& saId)
152 {
153     return std::find(updateVec_.begin(), updateVec_.end(), saId) != updateVec_.end();
154 }
155 
OpenSo(SaProfile & saProfile)156 void ParseUtil::OpenSo(SaProfile& saProfile)
157 {
158     if (saProfile.handle == nullptr) {
159         string fileName;
160         string libDir;
161         ParseLibPath(saProfile.libPath, fileName, libDir);
162         if (libDir != "lib64" && libDir != "lib") {
163             HILOGE("invalid libDir %{public}s", libDir.c_str());
164             return;
165         }
166         bool loadFromModuleUpdate = false;
167         Dl_namespace dlNs;
168         string updateLibPath = GetRealPath("/module_update/" + ToString(saProfile.saId) + "/" + libDir + "/"
169             + fileName);
170         if (IsUpdateSA(ToString(saProfile.saId)) && CheckPathExist(updateLibPath)) {
171             HILOGI("create namespace to load so");
172             Dl_namespace currentNs;
173             string nsName = "module_update_" + ToString(saProfile.saId);
174             dlns_init(&dlNs, nsName.c_str());
175             dlns_get(nullptr, &currentNs);
176 
177             string libLdPath = GetRealPath("/module_update/" + ToString(saProfile.saId) + "/" + libDir);
178             if (!libLdPath.empty()) {
179                 dlns_create(&dlNs, libLdPath.c_str());
180                 dlns_inherit(&dlNs, &currentNs, nullptr);
181                 loadFromModuleUpdate = true;
182             }
183         }
184 
185         string dlopenTag = ToString(saProfile.saId) + "_DLOPEN";
186         HITRACE_METER_NAME(HITRACE_TAG_SAMGR, dlopenTag);
187         int64_t begin = GetTickCount();
188         DlHandle handle = nullptr;
189         if (loadFromModuleUpdate) {
190             handle = dlopen_ns(&dlNs, updateLibPath.c_str(), RTLD_NOW);
191         }
192         if (handle == nullptr) {
193             handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW);
194         }
195         HILOGI("[PerformanceTest] SA:%{public}d OpenSo spend %{public}" PRId64 " ms",
196             saProfile.saId, GetTickCount() - begin);
197         if (handle == nullptr) {
198             ReportAddSystemAbilityFailed(saProfile.saId, fileName);
199             HILOGE("dlopen %{public}s failed with errno:%{public}s!", fileName.c_str(), dlerror());
200             return;
201         }
202         saProfile.handle = handle;
203     } else {
204         HILOGI("SA:%{public}d handle is not null", saProfile.saId);
205     }
206 }
207 
LoadSaLib(int32_t systemAbilityId)208 bool ParseUtil::LoadSaLib(int32_t systemAbilityId)
209 {
210     for (auto& saProfile : saProfiles_) {
211         if (saProfile.saId == systemAbilityId) {
212             OpenSo(saProfile);
213             return true;
214         }
215     }
216     return false;
217 }
218 
GetAllSaProfiles() const219 const std::list<SaProfile>& ParseUtil::GetAllSaProfiles() const
220 {
221     return saProfiles_;
222 }
223 
GetProfile(int32_t saId,SaProfile & saProfile)224 bool ParseUtil::GetProfile(int32_t saId, SaProfile& saProfile)
225 {
226     auto iter = std::find_if(saProfiles_.begin(), saProfiles_.end(), [saId](auto saProfile) {
227         return saProfile.saId == saId;
228     });
229     if (iter != saProfiles_.end()) {
230         saProfile = *iter;
231         return true;
232     }
233     return false;
234 }
235 
RemoveSaProfile(int32_t saId)236 void ParseUtil::RemoveSaProfile(int32_t saId)
237 {
238     saProfiles_.remove_if([saId] (auto saInfo) -> bool { return saInfo.saId == saId; });
239 }
240 
GetBootPriorityPara(const std::string & bootPhase)241 uint32_t ParseUtil::GetBootPriorityPara(const std::string& bootPhase)
242 {
243     if (bootPhase == BOOT_START_PHASE) {
244         return static_cast<uint32_t>(BOOT_START);
245     } else if (bootPhase == CORE_START_PHASE) {
246         return static_cast<uint32_t>(CORE_START);
247     } else {
248         return static_cast<uint32_t>(OTHER_START);
249     }
250 }
251 
ParseSaProfiles(const string & profilePath)252 bool ParseUtil::ParseSaProfiles(const string& profilePath)
253 {
254     HILOGD("profilePath:%{private}s", profilePath.c_str());
255     string realPath = GetRealPath(profilePath);
256     if (!CheckPathExist(realPath.c_str())) {
257         HILOGE("bad profile path!");
258         return false;
259     }
260 
261     if (Endswith(realPath, ".json")) {
262         return ParseJsonFile(realPath);
263     } else {
264         HILOGE("Invalid file format, please use json file!");
265         return false;
266     }
267 }
268 
Endswith(const std::string & src,const std::string & sub)269 bool ParseUtil::Endswith(const std::string& src, const std::string& sub)
270 {
271     return (src.length() >= sub.length() && (src.rfind(sub) == (src.length() - sub.length())));
272 }
273 
StringToMap(const std::string & eventStr)274 std::unordered_map<std::string, std::string> ParseUtil::StringToMap(const std::string& eventStr)
275 {
276     nlohmann::json eventJson = StringToJsonObj(eventStr);
277     std::unordered_map<std::string, std::string> eventMap = JsonObjToMap(eventJson);
278     return eventMap;
279 }
280 
StringToJsonObj(const std::string & eventStr)281 nlohmann::json ParseUtil::StringToJsonObj(const std::string& eventStr)
282 {
283     nlohmann::json jsonObj = nlohmann::json::object();
284     if (eventStr.empty()) {
285         return jsonObj;
286     }
287     nlohmann::json eventJson = nlohmann::json::parse(eventStr, nullptr, false);
288     if (eventJson.is_discarded()) {
289         HILOGE("parse eventStr to json failed");
290         return jsonObj;
291     }
292     if (!eventJson.is_object()) {
293         HILOGE("eventStr converted result is not a jsonObj");
294         return jsonObj;
295     }
296     return eventJson;
297 }
298 
JsonObjToMap(const nlohmann::json & eventJson)299 std::unordered_map<std::string, std::string> ParseUtil::JsonObjToMap(const nlohmann::json& eventJson)
300 {
301     std::unordered_map<std::string, std::string> eventMap;
302     if (eventJson.contains(EVENT_TYPE) && eventJson[EVENT_TYPE].is_string()) {
303         eventMap[EVENT_TYPE] = eventJson[EVENT_TYPE];
304     } else {
305         eventMap[EVENT_TYPE] = "";
306     }
307     if (eventJson.contains(EVENT_NAME) && eventJson[EVENT_NAME].is_string()) {
308         eventMap[EVENT_NAME] = eventJson[EVENT_NAME];
309     } else {
310         eventMap[EVENT_NAME] = "";
311     }
312     if (eventJson.contains(EVENT_VALUE) && eventJson[EVENT_VALUE].is_string()) {
313         eventMap[EVENT_VALUE] = eventJson[EVENT_VALUE];
314     } else {
315         eventMap[EVENT_VALUE] = "";
316     }
317     return eventMap;
318 }
319 
ParseJsonFile(const string & realPath)320 bool ParseUtil::ParseJsonFile(const string& realPath)
321 {
322     nlohmann::json profileJson;
323     bool result = ParseJsonObj(profileJson, realPath);
324     if (!result) {
325         HILOGE("json file parse error!");
326         return false;
327     }
328     HILOGI("profileJson:%{private}s", profileJson.dump().c_str());
329     string process;
330     GetStringFromJson(profileJson, SA_TAG_PROCESS, process);
331     if (process.empty()) {
332         HILOGE("profile format error: no process tag");
333         return false;
334     }
335     if (process.length() > MAX_JSON_STRING_LENGTH) {
336         HILOGE("profile format error: process is too long");
337         return false;
338     }
339     procName_ = Str8ToStr16(process);
340     if (profileJson.find(SA_TAG_SYSTEM_ABILITY) == profileJson.end()) {
341         HILOGE("system ability parse error!");
342         return false;
343     }
344     nlohmann::json& systemAbilityJson = profileJson.at(SA_TAG_SYSTEM_ABILITY);
345     HILOGI("systemAbilityJson:%{private}s", systemAbilityJson.dump().c_str());
346     if (!systemAbilityJson.is_array()) {
347         HILOGE("system ability is not array!");
348         return false;
349     }
350     size_t size = systemAbilityJson.size();
351     for (size_t i = 0; i < size; i++) {
352         SaProfile saProfile = { procName_ };
353         if (!ParseSystemAbility(saProfile, systemAbilityJson[i])) {
354             continue;
355         }
356         saProfiles_.emplace_back(saProfile);
357     }
358     return !saProfiles_.empty();
359 }
360 
ParseSystemAbility(SaProfile & saProfile,nlohmann::json & systemAbilityJson)361 bool ParseUtil::ParseSystemAbility(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
362 {
363     HILOGD("ParseSystemAbility begin");
364     GetInt32FromJson(systemAbilityJson, SA_TAG_NAME, saProfile.saId);
365     if (saProfile.saId == 0) {
366         HILOGE("profile format error: no name tag");
367         return false;
368     }
369     if (saProfile.saId < FIRST_SYS_ABILITY_ID || saProfile.saId > LAST_SYS_ABILITY_ID) {
370         HILOGE("profile format error: saId error");
371         return false;
372     }
373     GetStringFromJson(systemAbilityJson, SA_TAG_LIB_PATH, saProfile.libPath);
374     if (saProfile.libPath.empty()) {
375         HILOGE("profile format error: no libPath tag");
376         return false;
377     }
378     if (saProfile.libPath.length() > MAX_JSON_STRING_LENGTH) {
379         HILOGE("profile format error: libPath is too long");
380         return false;
381     }
382     GetBoolFromJson(systemAbilityJson, SA_TAG_RUN_ON_CREATE, saProfile.runOnCreate);
383     GetBoolFromJson(systemAbilityJson, SA_TAG_AUTO_RESTART, saProfile.autoRestart);
384     GetBoolFromJson(systemAbilityJson, SA_TAG_DISTRIBUTED, saProfile.distributed);
385     GetIntArrayFromJson(systemAbilityJson, SA_TAG_DEPEND, saProfile.dependSa);
386     GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT, saProfile.dependTimeout);
387     if (saProfile.dependTimeout == 0) {
388         GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY, saProfile.dependTimeout);
389     }
390     GetInt32FromJson(systemAbilityJson, SA_TAG_DUMP_LEVEL, saProfile.dumpLevel);
391     string capability;
392     GetStringFromJson(systemAbilityJson, SA_TAG_CAPABILITY, capability);
393     saProfile.capability = capability.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(capability) : u"";
394     string permission;
395     GetStringFromJson(systemAbilityJson, SA_TAG_PERMISSION, permission);
396     saProfile.permission = permission.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(permission) : u"";
397     string bootPhase;
398     GetStringFromJson(systemAbilityJson, SA_TAG_BOOT_PHASE, bootPhase);
399     saProfile.bootPhase = GetBootPriorityPara(bootPhase);
400     // parse start-on-demand tag
401     ParseStartOndemandTag(systemAbilityJson, SA_TAG_START_ON_DEMAND, saProfile.startOnDemand);
402     // parse stop-on-demand tag
403     ParseStopOndemandTag(systemAbilityJson, SA_TAG_STOP_ON_DEMAND, saProfile.stopOnDemand);
404     HILOGD("ParseSystemAbility end");
405     return true;
406 }
407 
ParseJsonTag(const nlohmann::json & systemAbilityJson,const std::string & jsonTag,nlohmann::json & onDemandJson)408 bool ParseUtil::ParseJsonTag(const nlohmann::json& systemAbilityJson, const std::string& jsonTag,
409     nlohmann::json& onDemandJson)
410 {
411     if (systemAbilityJson.find(jsonTag) == systemAbilityJson.end()) {
412         return false;
413     }
414     onDemandJson = systemAbilityJson.at(jsonTag);
415     if (!onDemandJson.is_object()) {
416         HILOGE("parse ondemand tag error");
417         return false;
418     }
419     return true;
420 }
421 
ParseOndemandTag(const nlohmann::json & onDemandJson,std::vector<OnDemandEvent> & onDemandEvents)422 void ParseUtil::ParseOndemandTag(const nlohmann::json& onDemandJson, std::vector<OnDemandEvent>& onDemandEvents)
423 {
424     GetOnDemandArrayFromJson(DEVICE_ONLINE, onDemandJson, SA_TAG_DEVICE_ON_LINE, onDemandEvents);
425     GetOnDemandArrayFromJson(SETTING_SWITCH, onDemandJson, SA_TAG_SETTING_SWITCH, onDemandEvents);
426     GetOnDemandArrayFromJson(COMMON_EVENT, onDemandJson, SA_TAG_COMMON_EVENT, onDemandEvents);
427     GetOnDemandArrayFromJson(PARAM, onDemandJson, SA_TAG_PARAM, onDemandEvents);
428     GetOnDemandArrayFromJson(TIMED_EVENT, onDemandJson, SA_TAG_TIEMD_EVENT, onDemandEvents);
429 }
430 
ParseStartOndemandTag(const nlohmann::json & systemAbilityJson,const std::string & jsonTag,StartOnDemand & startOnDemand)431 void ParseUtil::ParseStartOndemandTag(const nlohmann::json& systemAbilityJson,
432     const std::string& jsonTag, StartOnDemand& startOnDemand)
433 {
434     nlohmann::json onDemandJson;
435     if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) {
436         return;
437     }
438     ParseOndemandTag(onDemandJson, startOnDemand.onDemandEvents);
439     GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, startOnDemand.allowUpdate);
440 }
441 
ParseStopOndemandTag(const nlohmann::json & systemAbilityJson,const std::string & jsonTag,StopOnDemand & stopOnDemand)442 void ParseUtil::ParseStopOndemandTag(const nlohmann::json& systemAbilityJson,
443     const std::string& jsonTag, StopOnDemand& stopOnDemand)
444 {
445     nlohmann::json onDemandJson;
446     if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) {
447         return;
448     }
449     ParseOndemandTag(onDemandJson, stopOnDemand.onDemandEvents);
450     GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, stopOnDemand.allowUpdate);
451     GetInt32FromJson(onDemandJson, SA_TAG_RECYCLE_DELAYTIME, stopOnDemand.delayTime);
452 }
453 
GetOnDemandArrayFromJson(int32_t eventId,const nlohmann::json & obj,const std::string & key,std::vector<OnDemandEvent> & out)454 void ParseUtil::GetOnDemandArrayFromJson(int32_t eventId, const nlohmann::json& obj,
455     const std::string& key, std::vector<OnDemandEvent>& out)
456 {
457     if (obj.find(key.c_str()) != obj.end() && obj[key.c_str()].is_array()) {
458         for (auto& item : obj[key.c_str()]) {
459             std::string name;
460             GetStringFromJson(item, "name", name);
461             std::string value;
462             GetStringFromJson(item, "value", value);
463             std::vector<OnDemandCondition> conditions;
464             GetOnDemandConditionsFromJson(item, "conditions", conditions);
465             HILOGD("conditions size: %{public}zu", conditions.size());
466             bool enableOnce = false;
467             GetBoolFromJson(item, "enable-once", enableOnce);
468             if (!name.empty() && name.length() <= MAX_JSON_STRING_LENGTH &&
469                 value.length() <= MAX_JSON_STRING_LENGTH) {
470                 OnDemandEvent event = {eventId, name, value, -1, conditions, enableOnce};
471                 out.emplace_back(event);
472             }
473         }
474     }
475 }
476 
GetOnDemandConditionsFromJson(const nlohmann::json & obj,const std::string & key,std::vector<OnDemandCondition> & out)477 void ParseUtil::GetOnDemandConditionsFromJson(const nlohmann::json& obj,
478     const std::string& key, std::vector<OnDemandCondition>& out)
479 {
480     nlohmann::json conditionsJson;
481     if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_array()) {
482         return;
483     }
484     conditionsJson = obj.at(key.c_str());
485     for (auto& condition : conditionsJson) {
486         std::string type;
487         GetStringFromJson(condition, "eventId", type);
488         std::string name;
489         GetStringFromJson(condition, "name", name);
490         std::string value;
491         GetStringFromJson(condition, "value", value);
492         int32_t eventId = 0;
493         if (type == SA_TAG_DEVICE_ON_LINE) {
494             eventId = DEVICE_ONLINE;
495         } else if (type == SA_TAG_SETTING_SWITCH) {
496             eventId = SETTING_SWITCH;
497         } else if (type == SA_TAG_COMMON_EVENT) {
498             eventId = COMMON_EVENT;
499         } else if (type == SA_TAG_PARAM) {
500             eventId = PARAM;
501         } else if (type == SA_TAG_TIEMD_EVENT) {
502             eventId = TIMED_EVENT;
503         } else {
504             HILOGW("invalid condition eventId: %{public}s", type.c_str());
505             continue;
506         }
507         OnDemandCondition conditionEvent = {eventId, name, value};
508         out.emplace_back(conditionEvent);
509     }
510 }
511 
GetProcessName() const512 std::u16string ParseUtil::GetProcessName() const
513 {
514     return procName_;
515 }
516 
GetRealPath(const string & profilePath) const517 string ParseUtil::GetRealPath(const string& profilePath) const
518 {
519     char path[PATH_MAX] = {'\0'};
520     if (realpath(profilePath.c_str(), path) == nullptr) {
521         HILOGE("get real path fail");
522         return "";
523     }
524     string realPath(path);
525     return realPath;
526 }
527 
CheckPathExist(const string & profilePath)528 bool ParseUtil::CheckPathExist(const string& profilePath)
529 {
530     std::ifstream profileStream(profilePath.c_str());
531     return profileStream.good();
532 }
533 
ParseTrustConfig(const string & profilePath,std::map<std::u16string,std::set<int32_t>> & values)534 bool ParseUtil::ParseTrustConfig(const string& profilePath,
535     std::map<std::u16string, std::set<int32_t>>& values)
536 {
537     HILOGD("config path:%{private}s", profilePath.c_str());
538     string realPath = GetRealPath(profilePath);
539     if (!CheckPathExist(realPath.c_str())) {
540         HILOGE("bad profile path!");
541         return false;
542     }
543     nlohmann::json trustSaIdJson;
544     bool result = ParseJsonObj(trustSaIdJson, realPath);
545     if (!result) {
546         HILOGE("trust json file parse error!");
547         return false;
548     }
549     string process;
550     GetStringFromJson(trustSaIdJson, SA_TAG_PROCESS, process);
551     if (process.empty()) {
552         HILOGE("trust profile format error: no process tag");
553         return false;
554     }
555     if (process.length() > MAX_JSON_STRING_LENGTH) {
556         HILOGE("trust profile format error: process is too long");
557         return false;
558     }
559     auto& saIds = values[Str8ToStr16(process)];
560     GetIntArrayFromJson(trustSaIdJson, SA_TAG_SAID, saIds);
561     HILOGI("ParseTrustConfig realPath:%s, saIds size = %{public}zu", realPath.c_str(), saIds.size());
562     return true;
563 }
564 
ParseJsonObj(nlohmann::json & jsonObj,const string & jsonPath)565 bool ParseUtil::ParseJsonObj(nlohmann::json& jsonObj, const string& jsonPath)
566 {
567     std::ifstream jsonFileStream;
568     jsonFileStream.open(jsonPath.c_str(), std::ios::in);
569     if (!jsonFileStream.is_open()) {
570         HILOGE("open json file error!!");
571         return false;
572     }
573     std::ostringstream buffer;
574     char ch;
575     int32_t readSize = 0;
576     while (buffer && jsonFileStream.get(ch)) {
577         readSize++;
578         if (readSize < MAX_JSON_OBJECT_SIZE) {
579             buffer.put(ch);
580         } else {
581             jsonFileStream.close();
582             HILOGE("too big json file error!!");
583             return false;
584         }
585     }
586     jsonFileStream.close();
587     string jsonStr = buffer.str();
588     jsonObj = nlohmann::json::parse(jsonStr, nullptr, false);
589     if (jsonObj.is_discarded()) {
590         HILOGE("parse json obj error!!");
591         return false;
592     }
593     return true;
594 }
595 } // namespace OHOS
596