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