• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "event_json_parser.h"
17 
18 #include <algorithm>
19 #include <fstream>
20 
21 #include "cJSON.h"
22 #include "logger.h"
23 #include "sys_event_query.h"
24 
25 namespace OHOS {
26 namespace HiviewDFX {
27 static const char* BASE_EVENT_PAR[] = {"domain_", "name_", "type_", "time_", "level_",
28     "uid_", "tag_", "tz_", "pid_", "tid_", "traceid_", "spanid_", "pspanid_", "trace_flag_"};
29 static const char* EVENT_JSON_TYPE[] = {"FAULT", "STATISTIC", "SECURITY", "BEHAVIOR"};
30 
31 DEFINE_LOG_TAG("Event-JsonParser");
32 
EventJsonParser(const std::string & path)33 EventJsonParser::EventJsonParser(const std::string &path) : jsonRootValid(false)
34 {
35     std::ifstream fin(path, std::ifstream::binary);
36 #ifdef JSONCPP_VERSION_STRING
37     Json::CharReaderBuilder jsonRBuilder;
38     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
39     JSONCPP_STRING errs;
40     if (!parseFromStream(jsonRBuilder, fin, &root_, &errs)) {
41 #else
42     Json::Reader reader(Json::Features::strictMode());
43     if (!reader.parse(fin, root_)) {
44 #endif
45         HIVIEW_LOGE("parse json file failed, please check the style of json file: %{public}s", path.c_str());
46     } else {
47         jsonRootValid = true;
48     }
49 }
50 
51 EventJsonParser::~EventJsonParser() {}
52 
53 bool EventJsonParser::HandleEventJson(std::shared_ptr<SysEvent> &event) const
54 {
55     Json::Value eventJson;
56     std::string jsonStr = event->jsonExtraInfo_;
57 #ifdef JSONCPP_VERSION_STRING
58     Json::CharReaderBuilder jsonRBuilder;
59     Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
60     std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
61     JSONCPP_STRING errs;
62     if (!reader->parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), &eventJson, &errs)) {
63 #else
64     Json::Reader reader(Json::Features::strictMode());
65     if (!reader.parse(jsonStr, eventJson)) {
66 #endif
67         HIVIEW_LOGE("parse json file failed, please check the style of json file: %{public}s",
68             jsonStr.c_str());
69         return false;
70     }
71 
72     auto eventJsonNotComplete = !eventJson.isMember("domain_") || !eventJson["domain_"].isString() ||
73         !eventJson.isMember("name_") || !eventJson["name_"].isString() ||
74         !eventJson.isMember("type_") || !eventJson["type_"].isInt();
75     std::string domain = eventJson["domain_"].asString();
76     std::string name = eventJson["name_"].asString();
77     auto eventJsonHasNoDomain = !jsonRootValid || !root_.isObject() || !root_.isMember(domain) ||
78         !root_[domain].isObject() || !root_[domain].isMember(name) || !root_[domain][name].isObject() ||
79         !root_[domain][name].isMember("__BASE") || root_[domain][name]["__BASE"].isNull();
80     auto sysEventJson = root_[domain][name];
81     auto baseInfoNotValid = !CheckBaseInfo(sysEventJson["__BASE"], eventJson);
82     if (eventJsonNotComplete || eventJsonHasNoDomain || baseInfoNotValid) {
83         return false;
84     }
85 
86     auto eventNameList = eventJson.getMemberNames();
87     for (auto it = eventNameList.cbegin(); it != eventNameList.cend(); it++) {
88         std::string ps = *it;
89         if (std::find_if(std::cbegin(BASE_EVENT_PAR), std::cend(BASE_EVENT_PAR), [ps](const char* ele) {
90             return (ps.compare(ele) == 0); }) == std::cend(BASE_EVENT_PAR)) {
91             if (!CheckExtendInfo(ps, sysEventJson, eventJson)) {
92                 HIVIEW_LOGI("CheckExtendInfo fail, need to remove %{public}s ", ps.c_str());
93                 eventJson.removeMember(ps);
94             }
95         }
96     }
97     GetOrderlyJsonInfo(eventJson, jsonStr);
98     event->jsonExtraInfo_ = jsonStr;
99     return true;
100 }
101 
102 bool EventJsonParser::CheckBaseInfo(const Json::Value &sysBaseJson, Json::Value &eventJson) const
103 {
104     int eventJsonTypeValue = eventJson["type_"].asInt();
105     if ((eventJsonTypeValue < 1) || (eventJsonTypeValue > 4)) {
106         HIVIEW_LOGE("EventJson type is illegal parameter");
107         return false;
108     }
109     if (sysBaseJson["type"].asString().compare(EVENT_JSON_TYPE[eventJsonTypeValue - 1]) != 0) {
110         HIVIEW_LOGE("Check type error type %{public}s %{public}d",
111             sysBaseJson["type"].asString().c_str(), eventJson["type_"].asInt());
112         return false;
113     }
114 
115     if (!sysBaseJson.isMember("level")) {
116         HIVIEW_LOGE("sysBaseJson is not complete");
117         return false;
118     }
119     eventJson["level_"] = sysBaseJson["level"].asString();
120     if (sysBaseJson.isMember("tag")) {
121         eventJson["tag_"] = sysBaseJson["tag"].asString();
122     }
123     return true;
124 }
125 
126 bool EventJsonParser::CheckExtendInfo(const std::string &name, const Json::Value &sysEvent,
127     const Json::Value &eventJson) const
128 {
129     if (!sysEvent.isMember(name)) {
130         return false;
131     }
132     if (sysEvent[name].isMember("arrsize")) {
133         if (!eventJson[name].isArray() || eventJson[name].size() > sysEvent[name]["arrsize"].asUInt()) {
134             return false;
135         }
136         return JudgeDataType(sysEvent[name]["type"].asString(), eventJson[name][0]);
137     }
138     return JudgeDataType(sysEvent[name]["type"].asString(), eventJson[name]);
139 }
140 
141 bool EventJsonParser::JudgeDataType(const std::string &dataType, const Json::Value &eventJson) const
142 {
143     if (dataType.compare("BOOL") == 0) {
144         return eventJson.isBool();
145     } else if ((dataType.compare("INT8") == 0) || (dataType.compare("INT16") == 0) ||
146         (dataType.compare("INT32") == 0) || (dataType.compare("INT64") == 0)) {
147         return eventJson.isInt();
148     } else if ((dataType.compare("UINT8") == 0) || (dataType.compare("UINT16") == 0) ||
149         (dataType.compare("UINT32") == 0) || (dataType.compare("UINT64") == 0)) {
150         return eventJson.isUInt();
151     } else if ((dataType.compare("FLOAT") == 0) || (dataType.compare("DOUBLE") == 0)) {
152         return eventJson.isDouble();
153     } else if (dataType.compare("STRING") == 0) {
154         return eventJson.isString();
155     } else {
156         return false;
157     }
158 }
159 
160 void EventJsonParser::GetOrderlyJsonInfo(const Json::Value &eventJson, std::string &jsonStr) const
161 {
162     // convert JsonValue to the correct order by event->jsonExtraInfo_
163     cJSON *cJsonArr = cJSON_Parse(jsonStr.c_str());
164     if (cJsonArr == NULL) {
165         return;
166     }
167     int endJson = cJSON_GetArraySize(cJsonArr) - 1;
168     cJSON *item = NULL;
169 
170     // cJsonArr need to delete the item that failed the check by hisysevent.def
171     for (int i = endJson; i >= 0; i--) {
172         item = cJSON_GetArrayItem(cJsonArr, i);
173         if (!eventJson.isMember(item->string)) {
174             cJSON_DeleteItemFromArray(cJsonArr, i);
175         }
176     }
177 
178     // cJsonArr need to add "level_" and "tag_" by hisysevent.def, "level" is must-option
179     cJSON_AddStringToObject(cJsonArr, "level_", eventJson["level_"].asString().c_str());
180     if (eventJson.isMember("tag_")) {
181         cJSON_AddStringToObject(cJsonArr, "tag_", eventJson["tag_"].asString().c_str());
182     }
183 
184     // FreezeDetector needs to add
185     cJSON_AddStringToObject(cJsonArr, EventStore::EventCol::INFO.c_str(), "");
186 
187     char* jsonPtr =  cJSON_PrintUnformatted(cJsonArr);
188     if (jsonPtr != nullptr) {
189         jsonStr = std::string(jsonPtr);
190         cJSON_free(jsonPtr);
191     }
192     cJSON_Delete(cJsonArr);
193     return;
194 }
195 
196 std::string EventJsonParser::GetDefinedTagByDomainEventName(const std::string& domain,
197     const std::string& eventName) const
198 {
199     if (!jsonRootValid) {
200         return "";
201     }
202     auto eventJsonHasNoDomain = !root_.isObject() || !root_.isMember(domain) || !root_[domain].isObject()
203         || !root_[domain].isMember(eventName) || !root_[domain][eventName].isObject()
204         || !root_[domain][eventName].isMember("__BASE") || root_[domain][eventName]["__BASE"].isNull();
205     if (eventJsonHasNoDomain) {
206         return "";
207     }
208     auto sysEventBaseInfo = root_[domain][eventName]["__BASE"];
209     if (!sysEventBaseInfo.isMember("tag")) {
210         return "";
211     }
212     return sysEventBaseInfo["tag"].asString();
213 }
214 } // namespace HiviewDFX
215 } // namespace OHOS
216