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, ¤tNs);
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, ¤tNs, 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