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 <unistd.h>
22 #include <memory>
23 #include <sstream>
24 #include <vector>
25 #include <algorithm>
26 
27 #include "datetime_ex.h"
28 #include "hisysevent_adapter.h"
29 #include "hitrace_meter.h"
30 #include "sam_log.h"
31 #include "string_ex.h"
32 #include "samgr_xcollie.h"
33 
34 namespace OHOS {
35 using std::string;
36 
37 namespace {
38 constexpr const char* EVENT_TYPE = "eventId";
39 constexpr const char* EVENT_NAME = "name";
40 constexpr const char* EVENT_VALUE = "value";
41 constexpr const char* SA_TAG_SYSTEM_ABILITY = "systemability";
42 constexpr const char* SA_TAG_PROCESS = "process";
43 constexpr const char* SA_TAG_LIB_PATH = "libpath";
44 constexpr const char* SA_TAG_NAME = "name";
45 constexpr const char* SA_TAG_DEPEND = "depend";
46 constexpr const char* SA_TAG_DEPEND_TIMEOUT = "depend-time-out";
47 constexpr const char* SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY = "depend_time_out";
48 constexpr const char* SA_TAG_RUN_ON_CREATE = "run-on-create";
49 constexpr const char* SA_TAG_MODULE_UPDATE = "module-update";
50 constexpr const char* SA_TAG_AUTO_RESTART = "auto-restart";
51 constexpr const char* SA_TAG_DISTRIBUTED = "distributed";
52 constexpr const char* SA_TAG_CACHE_COMMON_EVENT = "cache-common-event";
53 constexpr const char* SA_TAG_DUMP_LEVEL = "dump-level";
54 constexpr const char* SA_TAG_CAPABILITY = "capability";
55 constexpr const char* SA_TAG_PERMISSION = "permission";
56 constexpr const char* SA_TAG_BOOT_PHASE = "bootphase";
57 constexpr const char* SA_TAG_SAID = "said";
58 constexpr const char* SA_TAG_START_ON_DEMAND = "start-on-demand";
59 constexpr const char* SA_TAG_STOP_ON_DEMAND = "stop-on-demand";
60 constexpr const char* SA_TAG_ALLOW_UPDATE = "allow-update";
61 constexpr const char* SA_TAG_RECYCLE_DELAYTIME = "recycle-delaytime";
62 constexpr const char* SA_TAG_DEVICE_ON_LINE = "deviceonline";
63 constexpr const char* SA_TAG_SETTING_SWITCH = "settingswitch";
64 constexpr const char* SA_TAG_COMMON_EVENT = "commonevent";
65 constexpr const char* SA_TAG_PARAM = "param";
66 constexpr const char* SA_TAG_TIEMD_EVENT = "timedevent";
67 constexpr const char* SA_TAG_RECYCLE_STRATEGY = "recycle-strategy";
68 constexpr const char* SA_TAG_EXTENSION = "extension";
69 constexpr int32_t MAX_JSON_OBJECT_SIZE = 50 * 1024;
70 constexpr int32_t MAX_JSON_STRING_LENGTH = 128;
71 constexpr int32_t FIRST_SYS_ABILITY_ID = 0x00000000;
72 constexpr int32_t LAST_SYS_ABILITY_ID = 0x00ffffff;
73 constexpr int32_t MAX_EXTENSIONO_NUM = 100;
74 constexpr int32_t MAX_DLOPEN_SECONDS = 60;
75 constexpr const char* BOOT_START_PHASE = "BootStartPhase";
76 constexpr const char* CORE_START_PHASE = "CoreStartPhase";
77 constexpr const char* HIGH_LOAD_PRIORITY = "HighPriority";
78 constexpr const char* MEDIUM_LOAD_PRIORITY = "MediumPriority";
79 
80 enum {
81     BOOT_START = 1,
82     CORE_START = 2,
83     OTHER_START = 3,
84 };
85 
86 enum {
87     EQ = 1,
88     GREATER_EQ = 2,
89     GREATER = 3,
90     LESS_EQ = 4,
91     LESS = 5
92 };
93 }
94 
~ParseUtil()95 ParseUtil::~ParseUtil()
96 {
97     ClearResource();
98 }
99 
CloseHandle(SaProfile & saProfile)100 void ParseUtil::CloseHandle(SaProfile& saProfile)
101 {
102     if (saProfile.handle == nullptr) {
103         return;
104     }
105     int32_t ret = dlclose(saProfile.handle);
106     if (ret) {
107         HILOGW("close handle failed with errno:%{public}d!", errno);
108     }
109     saProfile.handle = nullptr;
110 }
111 
CloseSo()112 void ParseUtil::CloseSo()
113 {
114     for (auto& saProfile : saProfiles_) {
115         CloseHandle(saProfile);
116     }
117 }
118 
CloseSo(int32_t systemAbilityId)119 void ParseUtil::CloseSo(int32_t systemAbilityId)
120 {
121     for (auto& saProfile : saProfiles_) {
122         if (saProfile.saId == systemAbilityId) {
123             CloseHandle(saProfile);
124             break;
125         }
126     }
127 }
128 
ClearResource()129 void ParseUtil::ClearResource()
130 {
131     CloseSo();
132     saProfiles_.clear();
133 }
134 
OpenSo(uint32_t bootPhase)135 void ParseUtil::OpenSo(uint32_t bootPhase)
136 {
137     for (auto& saProfile : saProfiles_) {
138         if (saProfile.runOnCreate && saProfile.bootPhase == bootPhase) {
139             OpenSo(saProfile);
140         }
141     }
142 }
143 
OpenSo(SaProfile & saProfile)144 void ParseUtil::OpenSo(SaProfile& saProfile)
145 {
146     if (saProfile.handle == nullptr) {
147         string dlopenTag = ToString(saProfile.saId) + "_DLOPEN";
148         HITRACE_METER_NAME(HITRACE_TAG_SAMGR, dlopenTag);
149         int64_t begin = GetTickCount();
150         DlHandle handle = nullptr;
151         if (saProfile.runOnCreate) {
152             handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW);
153         } else {
154             SamgrXCollie samgrXCollie("safwk--openso_" + ToString(saProfile.saId), MAX_DLOPEN_SECONDS);
155             handle = dlopen(saProfile.libPath.c_str(), RTLD_NOW);
156         }
157         int64_t duration = GetTickCount() - begin;
158         ReportSaLoadDuration(saProfile.saId, SA_LOAD_OPENSO, duration);
159         KHILOGI("SA:%{public}d OpenSo %{public}" PRId64 "ms",
160             saProfile.saId, duration);
161         if (handle == nullptr) {
162             std::vector<string> libPathVec;
163             string fileName = "";
164             SplitStr(saProfile.libPath, "/", libPathVec);
165             if (libPathVec.size() > 0) {
166                 fileName = libPathVec[libPathVec.size() - 1];
167             }
168             ReportAddSystemAbilityFailed(saProfile.saId, getpid(), getuid(), fileName);
169             HILOGE("SA:%{public}d dlopen %{public}s failed with errno:%{public}s!",
170                 saProfile.saId, fileName.c_str(), dlerror());
171             return;
172         }
173         saProfile.handle = handle;
174     } else {
175         KHILOGI("SA:%{public}d handle is not null", saProfile.saId);
176     }
177 }
178 
LoadSaLib(int32_t systemAbilityId)179 bool ParseUtil::LoadSaLib(int32_t systemAbilityId)
180 {
181     for (auto& saProfile : saProfiles_) {
182         if (saProfile.saId == systemAbilityId) {
183             OpenSo(saProfile);
184             return true;
185         }
186     }
187     return false;
188 }
189 
GetAllSaProfiles() const190 const std::list<SaProfile>& ParseUtil::GetAllSaProfiles() const
191 {
192     return saProfiles_;
193 }
194 
GetProfile(int32_t saId,SaProfile & saProfile)195 bool ParseUtil::GetProfile(int32_t saId, SaProfile& saProfile)
196 {
197     auto iter = std::find_if(saProfiles_.begin(), saProfiles_.end(), [saId](auto saProfile) {
198         return saProfile.saId == saId;
199     });
200     if (iter != saProfiles_.end()) {
201         saProfile = *iter;
202         return true;
203     }
204     return false;
205 }
206 
RemoveSaProfile(int32_t saId)207 void ParseUtil::RemoveSaProfile(int32_t saId)
208 {
209     saProfiles_.remove_if([saId] (auto saInfo) -> bool { return saInfo.saId == saId; });
210 }
211 
GetBootPriorityPara(const std::string & bootPhase)212 uint32_t ParseUtil::GetBootPriorityPara(const std::string& bootPhase)
213 {
214     if (bootPhase == BOOT_START_PHASE) {
215         return static_cast<uint32_t>(BOOT_START);
216     } else if (bootPhase == CORE_START_PHASE) {
217         return static_cast<uint32_t>(CORE_START);
218     } else {
219         return static_cast<uint32_t>(OTHER_START);
220     }
221 }
222 
GetOndemandPriorityPara(const std::string & loadPriority)223 uint32_t ParseUtil::GetOndemandPriorityPara(const std::string& loadPriority)
224 {
225     if (loadPriority == HIGH_LOAD_PRIORITY) {
226         return static_cast<uint32_t>(HIGH_PRIORITY);
227     } else if (loadPriority == MEDIUM_LOAD_PRIORITY) {
228         return static_cast<uint32_t>(MEDIUM_PRIORITY);
229     } else {
230         return static_cast<uint32_t>(LOW_PRIORITY);
231     }
232 }
233 
ParseSaProfiles(const string & profilePath)234 bool ParseUtil::ParseSaProfiles(const string& profilePath)
235 {
236     HILOGD("profilePath:%{private}s", profilePath.c_str());
237     string realPath = GetRealPath(profilePath);
238     if (!CheckPathExist(realPath.c_str())) {
239         HILOGE("bad profile path!");
240         return false;
241     }
242 
243     if (Endswith(realPath, ".json")) {
244         return ParseJsonFile(realPath);
245     } else {
246         HILOGE("Invalid file format, please use json file!");
247         return false;
248     }
249 }
250 
Endswith(const std::string & src,const std::string & sub)251 bool ParseUtil::Endswith(const std::string& src, const std::string& sub)
252 {
253     return (src.length() >= sub.length() && (src.rfind(sub) == (src.length() - sub.length())));
254 }
255 
StringToMap(const std::string & eventStr)256 std::unordered_map<std::string, std::string> ParseUtil::StringToMap(const std::string& eventStr)
257 {
258     nlohmann::json eventJson = StringToJsonObj(eventStr);
259     std::unordered_map<std::string, std::string> eventMap = JsonObjToMap(eventJson);
260     return eventMap;
261 }
262 
StringToJsonObj(const std::string & eventStr)263 nlohmann::json ParseUtil::StringToJsonObj(const std::string& eventStr)
264 {
265     nlohmann::json jsonObj = nlohmann::json::object();
266     if (eventStr.empty()) {
267         return jsonObj;
268     }
269     nlohmann::json eventJson = nlohmann::json::parse(eventStr, nullptr, false);
270     if (eventJson.is_discarded()) {
271         HILOGE("parse eventStr to json failed");
272         return jsonObj;
273     }
274     if (!eventJson.is_object()) {
275         HILOGE("eventStr converted result is not a jsonObj");
276         return jsonObj;
277     }
278     return eventJson;
279 }
280 
JsonObjToMap(const nlohmann::json & eventJson)281 std::unordered_map<std::string, std::string> ParseUtil::JsonObjToMap(const nlohmann::json& eventJson)
282 {
283     std::unordered_map<std::string, std::string> eventMap;
284     if (eventJson.contains(EVENT_TYPE) && eventJson[EVENT_TYPE].is_string()) {
285         eventMap[EVENT_TYPE] = eventJson[EVENT_TYPE];
286     } else {
287         eventMap[EVENT_TYPE] = "";
288     }
289     if (eventJson.contains(EVENT_NAME) && eventJson[EVENT_NAME].is_string()) {
290         eventMap[EVENT_NAME] = eventJson[EVENT_NAME];
291     } else {
292         eventMap[EVENT_NAME] = "";
293     }
294     if (eventJson.contains(EVENT_VALUE) && eventJson[EVENT_VALUE].is_string()) {
295         eventMap[EVENT_VALUE] = eventJson[EVENT_VALUE];
296     } else {
297         eventMap[EVENT_VALUE] = "";
298     }
299     return eventMap;
300 }
301 
ParseJsonFile(const string & realPath)302 bool ParseUtil::ParseJsonFile(const string& realPath)
303 {
304     nlohmann::json profileJson;
305     bool result = ParseJsonObj(profileJson, realPath);
306     if (!result) {
307         HILOGE("json file parse error!");
308         return false;
309     }
310     HILOGD("profileJson:%{private}s", profileJson.dump().c_str());
311     string process;
312     GetStringFromJson(profileJson, SA_TAG_PROCESS, process);
313     if (process.empty()) {
314         HILOGE("profile format error: no process tag");
315         return false;
316     }
317     if (process.length() > MAX_JSON_STRING_LENGTH) {
318         HILOGE("profile format error: process is too long");
319         return false;
320     }
321     procName_ = Str8ToStr16(process);
322     if (profileJson.find(SA_TAG_SYSTEM_ABILITY) == profileJson.end()) {
323         HILOGE("system ability parse error!");
324         return false;
325     }
326     nlohmann::json& systemAbilityJson = profileJson.at(SA_TAG_SYSTEM_ABILITY);
327     HILOGD("systemAbilityJson:%{private}s", systemAbilityJson.dump().c_str());
328     if (!systemAbilityJson.is_array()) {
329         HILOGE("system ability is not array!");
330         return false;
331     }
332     size_t size = systemAbilityJson.size();
333     for (size_t i = 0; i < size; i++) {
334         SaProfile saProfile = { procName_ };
335         if (!ParseSystemAbility(saProfile, systemAbilityJson[i])) {
336             continue;
337         }
338         saProfiles_.emplace_back(saProfile);
339     }
340     return !saProfiles_.empty();
341 }
342 
ParseSystemAbilityGetExtension(SaProfile & saProfile,nlohmann::json & systemAbilityJson)343 bool ParseUtil::ParseSystemAbilityGetExtension(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
344 {
345     if ((systemAbilityJson.find(SA_TAG_EXTENSION) != systemAbilityJson.end()) &&
346         (systemAbilityJson[SA_TAG_EXTENSION].is_array())) {
347         for (auto& item : systemAbilityJson[SA_TAG_EXTENSION]) {
348             std::string extension = item.get<std::string>();
349             if (extension.length() > MAX_JSON_STRING_LENGTH) {
350                 HILOGE("profile format error: extension() len exceed limit");
351                 return false;
352             }
353             if (saProfile.extension.size() >= MAX_EXTENSIONO_NUM) {
354                 HILOGE("profile format error: extension num exceed limit");
355                 return false;
356             }
357 
358             if (std::find(saProfile.extension.begin(), saProfile.extension.end(), extension) ==
359                 saProfile.extension.end()) {
360                 saProfile.extension.push_back(extension);
361             }
362         }
363     }
364     return true;
365 }
366 
ParseSystemAbilityGetSaBaseInfo(SaProfile & saProfile,nlohmann::json & systemAbilityJson)367 bool ParseUtil::ParseSystemAbilityGetSaBaseInfo(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
368 {
369     GetInt32FromJson(systemAbilityJson, SA_TAG_NAME, saProfile.saId);
370     if (saProfile.saId == 0) {
371         HILOGE("profile format error: no name tag");
372         return false;
373     }
374     if (saProfile.saId < FIRST_SYS_ABILITY_ID || saProfile.saId > LAST_SYS_ABILITY_ID) {
375         HILOGE("profile format error: saId error");
376         return false;
377     }
378     GetStringFromJson(systemAbilityJson, SA_TAG_LIB_PATH, saProfile.libPath);
379     if (saProfile.libPath.empty()) {
380         HILOGE("profile format error: no libPath tag");
381         return false;
382     }
383     if (saProfile.libPath.length() > MAX_JSON_STRING_LENGTH) {
384         HILOGE("profile format error: libPath is too long");
385         return false;
386     }
387     return true;
388 }
389 
ParseSystemAbilityGetSaExtInfo(SaProfile & saProfile,nlohmann::json & systemAbilityJson)390 bool ParseUtil::ParseSystemAbilityGetSaExtInfo(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
391 {
392     GetBoolFromJson(systemAbilityJson, SA_TAG_RUN_ON_CREATE, saProfile.runOnCreate);
393     GetBoolFromJson(systemAbilityJson, SA_TAG_MODULE_UPDATE, saProfile.moduleUpdate);
394     GetBoolFromJson(systemAbilityJson, SA_TAG_AUTO_RESTART, saProfile.autoRestart);
395     GetBoolFromJson(systemAbilityJson, SA_TAG_DISTRIBUTED, saProfile.distributed);
396     GetBoolFromJson(systemAbilityJson, SA_TAG_CACHE_COMMON_EVENT, saProfile.cacheCommonEvent);
397     GetIntArrayFromJson(systemAbilityJson, SA_TAG_DEPEND, saProfile.dependSa);
398     GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT, saProfile.dependTimeout);
399     if (saProfile.dependTimeout == 0) {
400         GetInt32FromJson(systemAbilityJson, SA_TAG_DEPEND_TIMEOUT_COMPATIBILITY, saProfile.dependTimeout);
401     }
402     GetInt32FromJson(systemAbilityJson, SA_TAG_DUMP_LEVEL, saProfile.dumpLevel);
403     string capability;
404     GetStringFromJson(systemAbilityJson, SA_TAG_CAPABILITY, capability);
405     saProfile.capability = capability.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(capability) : u"";
406     string permission;
407     GetStringFromJson(systemAbilityJson, SA_TAG_PERMISSION, permission);
408     saProfile.permission = permission.length() <= MAX_JSON_STRING_LENGTH ? Str8ToStr16(permission) : u"";
409     string bootPhase;
410     GetStringFromJson(systemAbilityJson, SA_TAG_BOOT_PHASE, bootPhase);
411     saProfile.bootPhase = GetBootPriorityPara(bootPhase);
412     // parse start-on-demand tag
413     ParseStartOndemandTag(systemAbilityJson, SA_TAG_START_ON_DEMAND, saProfile.startOnDemand);
414     // parse stop-on-demand tag
415     ParseStopOndemandTag(systemAbilityJson, SA_TAG_STOP_ON_DEMAND, saProfile.stopOnDemand);
416     string recycleStrategy;
417     GetStringFromJson(systemAbilityJson, SA_TAG_RECYCLE_STRATEGY, recycleStrategy);
418     if (!CheckRecycleStrategy(recycleStrategy, saProfile.recycleStrategy)) {
419         HILOGE("profile format error: recycleStrategy: %{public}s is not immediately or low-memory",
420             recycleStrategy.c_str());
421         return false;
422     }
423     if (!ParseSystemAbilityGetExtension(saProfile, systemAbilityJson)) {
424         return false;
425     }
426     return true;
427 }
428 
ParseSystemAbility(SaProfile & saProfile,nlohmann::json & systemAbilityJson)429 bool ParseUtil::ParseSystemAbility(SaProfile& saProfile, nlohmann::json& systemAbilityJson)
430 {
431     HILOGD("ParseSystemAbility begin");
432     if (!ParseSystemAbilityGetSaBaseInfo(saProfile, systemAbilityJson)) {
433         return false;
434     }
435     if (!ParseSystemAbilityGetSaExtInfo(saProfile, systemAbilityJson)) {
436         return false;
437     }
438     HILOGD("ParseSystemAbility end");
439     return true;
440 }
441 
CheckRecycleStrategy(const std::string & recycleStrategyStr,int32_t & recycleStrategy)442 bool ParseUtil::CheckRecycleStrategy(const std::string& recycleStrategyStr, int32_t& recycleStrategy)
443 {
444     if (recycleStrategyStr == "" || recycleStrategyStr == "immediately") {
445         recycleStrategy = IMMEDIATELY;
446         return true;
447     } else if (recycleStrategyStr == "low-memory") {
448         recycleStrategy = LOW_MEMORY;
449         return true;
450     }
451     return false;
452 }
453 
ParseJsonTag(const nlohmann::json & systemAbilityJson,const std::string & jsonTag,nlohmann::json & onDemandJson)454 bool ParseUtil::ParseJsonTag(const nlohmann::json& systemAbilityJson, const std::string& jsonTag,
455     nlohmann::json& onDemandJson)
456 {
457     if (systemAbilityJson.find(jsonTag) == systemAbilityJson.end()) {
458         return false;
459     }
460     onDemandJson = systemAbilityJson.at(jsonTag);
461     if (!onDemandJson.is_object()) {
462         HILOGE("parse ondemand tag error");
463         return false;
464     }
465     return true;
466 }
467 
ParseOndemandTag(const nlohmann::json & onDemandJson,std::vector<OnDemandEvent> & onDemandEvents)468 void ParseUtil::ParseOndemandTag(const nlohmann::json& onDemandJson, std::vector<OnDemandEvent>& onDemandEvents)
469 {
470     GetOnDemandArrayFromJson(DEVICE_ONLINE, onDemandJson, SA_TAG_DEVICE_ON_LINE, onDemandEvents);
471     GetOnDemandArrayFromJson(SETTING_SWITCH, onDemandJson, SA_TAG_SETTING_SWITCH, onDemandEvents);
472     GetOnDemandArrayFromJson(COMMON_EVENT, onDemandJson, SA_TAG_COMMON_EVENT, onDemandEvents);
473     GetOnDemandArrayFromJson(PARAM, onDemandJson, SA_TAG_PARAM, onDemandEvents);
474     GetOnDemandArrayFromJson(TIMED_EVENT, onDemandJson, SA_TAG_TIEMD_EVENT, onDemandEvents);
475 }
476 
ParseStartOndemandTag(const nlohmann::json & systemAbilityJson,const std::string & jsonTag,StartOnDemand & startOnDemand)477 void ParseUtil::ParseStartOndemandTag(const nlohmann::json& systemAbilityJson,
478     const std::string& jsonTag, StartOnDemand& startOnDemand)
479 {
480     nlohmann::json onDemandJson;
481     if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) {
482         return;
483     }
484     ParseOndemandTag(onDemandJson, startOnDemand.onDemandEvents);
485     GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, startOnDemand.allowUpdate);
486 }
487 
ParseStopOndemandTag(const nlohmann::json & systemAbilityJson,const std::string & jsonTag,StopOnDemand & stopOnDemand)488 void ParseUtil::ParseStopOndemandTag(const nlohmann::json& systemAbilityJson,
489     const std::string& jsonTag, StopOnDemand& stopOnDemand)
490 {
491     nlohmann::json onDemandJson;
492     if (!ParseJsonTag(systemAbilityJson, jsonTag, onDemandJson)) {
493         return;
494     }
495     ParseOndemandTag(onDemandJson, stopOnDemand.onDemandEvents);
496     GetBoolFromJson(onDemandJson, SA_TAG_ALLOW_UPDATE, stopOnDemand.allowUpdate);
497     GetInt32FromJson(onDemandJson, SA_TAG_RECYCLE_DELAYTIME, stopOnDemand.delayTime);
498 }
499 
GetOnDemandArrayFromJson(int32_t eventId,const nlohmann::json & obj,const std::string & key,std::vector<OnDemandEvent> & out)500 void ParseUtil::GetOnDemandArrayFromJson(int32_t eventId, const nlohmann::json& obj,
501     const std::string& key, std::vector<OnDemandEvent>& out)
502 {
503     if (obj.find(key.c_str()) != obj.end() && obj[key.c_str()].is_array()) {
504         for (auto& item : obj[key.c_str()]) {
505             std::string name;
506             GetStringFromJson(item, "name", name);
507             std::string value;
508             GetStringFromJson(item, "value", value);
509             bool persistence = false;
510             GetBoolFromJson(item, "persistence", persistence);
511             std::vector<OnDemandCondition> conditions;
512             GetOnDemandConditionsFromJson(item, "conditions", conditions);
513             HILOGD("conditions size: %{public}zu", conditions.size());
514             bool enableOnce = false;
515             GetBoolFromJson(item, "enable-once", enableOnce);
516             std::string priority;
517             GetStringFromJson(item, "load-priority", priority);
518             uint32_t loadPriority = GetOndemandPriorityPara(priority);
519             std::map<std::string, std::string> extraMessages;
520             GetOnDemandExtraMessagesFromJson(item, "extra-messages", extraMessages);
521             HILOGD("extraMessages size: %{public}zu", extraMessages.size());
522             if (!name.empty() && name.length() <= MAX_JSON_STRING_LENGTH &&
523                 value.length() <= MAX_JSON_STRING_LENGTH) {
524                 OnDemandEvent event = {eventId, name, value, -1, persistence,
525                     conditions, enableOnce, loadPriority, extraMessages};
526                 out.emplace_back(event);
527             }
528         }
529     }
530 }
531 
GetOnDemandExtraMessagesFromJson(const nlohmann::json & obj,const std::string & key,std::map<std::string,std::string> & out)532 void ParseUtil::GetOnDemandExtraMessagesFromJson(const nlohmann::json& obj,
533     const std::string& key, std::map<std::string, std::string>& out)
534 {
535     if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_object()) {
536         return;
537     }
538     for (auto &it: obj[key.c_str()].items()) {
539         if (it.value().is_string()) {
540             out[it.key()] = it.value();
541         } else {
542             HILOGW("extra-mesasge: not string type");
543         }
544     }
545 }
546 
GetOnDemandConditionsFromJson(const nlohmann::json & obj,const std::string & key,std::vector<OnDemandCondition> & out)547 void ParseUtil::GetOnDemandConditionsFromJson(const nlohmann::json& obj,
548     const std::string& key, std::vector<OnDemandCondition>& out)
549 {
550     nlohmann::json conditionsJson;
551     if (obj.find(key.c_str()) == obj.end() || !obj[key.c_str()].is_array()) {
552         return;
553     }
554     conditionsJson = obj.at(key.c_str());
555     for (auto& condition : conditionsJson) {
556         std::string type;
557         GetStringFromJson(condition, "eventId", type);
558         std::string name;
559         GetStringFromJson(condition, "name", name);
560         std::string value;
561         GetStringFromJson(condition, "value", value);
562         int32_t eventId = 0;
563         if (type == SA_TAG_DEVICE_ON_LINE) {
564             eventId = DEVICE_ONLINE;
565         } else if (type == SA_TAG_SETTING_SWITCH) {
566             eventId = SETTING_SWITCH;
567         } else if (type == SA_TAG_COMMON_EVENT) {
568             eventId = COMMON_EVENT;
569         } else if (type == SA_TAG_PARAM) {
570             eventId = PARAM;
571         } else if (type == SA_TAG_TIEMD_EVENT) {
572             eventId = TIMED_EVENT;
573         } else {
574             HILOGW("invalid condition eventId: %{public}s", type.c_str());
575             continue;
576         }
577         std::map<std::string, std::string> extraMessages;
578         GetOnDemandExtraMessagesFromJson(condition, "extra-messages", extraMessages);
579         OnDemandCondition conditionEvent = {eventId, name, value, extraMessages};
580         out.emplace_back(conditionEvent);
581     }
582 }
583 
GetProcessName() const584 std::u16string ParseUtil::GetProcessName() const
585 {
586     return procName_;
587 }
588 
GetRealPath(const string & profilePath) const589 string ParseUtil::GetRealPath(const string& profilePath) const
590 {
591     char path[PATH_MAX] = {'\0'};
592     if (realpath(profilePath.c_str(), path) == nullptr) {
593         HILOGD("get real path fail");
594         return "";
595     }
596     string realPath(path);
597     return realPath;
598 }
599 
CheckPathExist(const string & profilePath)600 bool ParseUtil::CheckPathExist(const string& profilePath)
601 {
602     std::ifstream profileStream(profilePath.c_str());
603     return profileStream.good();
604 }
605 
ParseTrustConfig(const string & profilePath,std::map<std::u16string,std::set<int32_t>> & values)606 bool ParseUtil::ParseTrustConfig(const string& profilePath,
607     std::map<std::u16string, std::set<int32_t>>& values)
608 {
609     HILOGD("config path:%{private}s", profilePath.c_str());
610     string realPath = GetRealPath(profilePath);
611     if (!CheckPathExist(realPath.c_str())) {
612         HILOGE("bad profile path!");
613         return false;
614     }
615     nlohmann::json trustSaIdJson;
616     bool result = ParseJsonObj(trustSaIdJson, realPath);
617     if (!result) {
618         HILOGE("trust json file parse error!");
619         return false;
620     }
621     string process;
622     GetStringFromJson(trustSaIdJson, SA_TAG_PROCESS, process);
623     if (process.empty()) {
624         HILOGE("trust profile format error: no process tag");
625         return false;
626     }
627     if (process.length() > MAX_JSON_STRING_LENGTH) {
628         HILOGE("trust profile format error: process is too long");
629         return false;
630     }
631     auto& saIds = values[Str8ToStr16(process)];
632     GetIntArrayFromJson(trustSaIdJson, SA_TAG_SAID, saIds);
633     HILOGI("ParseTrustConfig realPath:%{public}s, saIds size = %{public}zu", realPath.c_str(), saIds.size());
634     return true;
635 }
636 
ParseJsonObj(nlohmann::json & jsonObj,const string & jsonPath)637 bool ParseUtil::ParseJsonObj(nlohmann::json& jsonObj, const string& jsonPath)
638 {
639     std::ifstream jsonFileStream;
640     jsonFileStream.open(jsonPath.c_str(), std::ios::in);
641     if (!jsonFileStream.is_open()) {
642         HILOGE("open json file error!!");
643         return false;
644     }
645     std::ostringstream buffer;
646     char ch;
647     int32_t readSize = 0;
648     while (buffer && jsonFileStream.get(ch)) {
649         readSize++;
650         if (readSize < MAX_JSON_OBJECT_SIZE) {
651             buffer.put(ch);
652         } else {
653             jsonFileStream.close();
654             HILOGE("too big json file error!!");
655             return false;
656         }
657     }
658     jsonFileStream.close();
659     string jsonStr = buffer.str();
660     jsonObj = nlohmann::json::parse(jsonStr, nullptr, false);
661     if (jsonObj.is_discarded()) {
662         HILOGE("parse json obj error!!");
663         return false;
664     }
665     return true;
666 }
667 
CheckLogicRelationship(const std::string & state,const std::string & profile)668 bool ParseUtil::CheckLogicRelationship(const std::string& state, const std::string& profile)
669 {
670     HILOGD("CheckLogicRelationship State:%{public}s || Profile:%{public}s", state.c_str(), profile.c_str());
671     if (profile.empty() || state == profile) {
672         return true;
673     }
674     if (state.empty()) {
675         return false;
676     }
677     int32_t logicRelationship = EQ;
678     int32_t valueStartPosition = 0;
679     if (profile[0] == '>') {
680         valueStartPosition ++;
681         if (profile[1] == '=') {
682             valueStartPosition ++;
683             logicRelationship = GREATER_EQ;
684         } else {
685             logicRelationship = GREATER;
686         }
687     } else if (profile[0] == '<') {
688         valueStartPosition ++;
689         if (profile[1] == '=') {
690             valueStartPosition ++;
691             logicRelationship = LESS_EQ;
692         } else {
693             logicRelationship = LESS;
694         }
695     }
696     int32_t stateInt, profileInt;
697     if (!StrToInt(profile.substr(valueStartPosition, profile.length() - 1), profileInt)) {
698         return false;
699     }
700     if (!StrToInt(state, stateInt)) {
701         return false;
702     }
703     if (logicRelationship == EQ) {
704         return stateInt == profileInt;
705     } else if (logicRelationship == GREATER_EQ) {
706         return stateInt >= profileInt;
707     } else if (logicRelationship == GREATER) {
708         return stateInt > profileInt;
709     } else if (logicRelationship == LESS_EQ) {
710         return stateInt <= profileInt;
711     } else if (logicRelationship == LESS) {
712         return stateInt < profileInt;
713     }
714     return false;
715 }
716 } // namespace OHOS
717