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 "napi_hisysevent_util.h"
17
18 #include <cinttypes>
19 #include <tuple>
20 #include <variant>
21
22 #include "def.h"
23 #include "hilog/log.h"
24 #include "ipc_skeleton.h"
25 #include "json/json.h"
26 #include "ret_code.h"
27 #include "ret_def.h"
28 #include "stringfilter.h"
29 #include "accesstoken_kit.h"
30
31 #undef LOG_DOMAIN
32 #define LOG_DOMAIN 0xD002D08
33
34 #undef LOG_TAG
35 #define LOG_TAG "NAPI_HISYSEVENT_UTIL"
36
37 namespace OHOS {
38 namespace HiviewDFX {
39 namespace {
40 constexpr uint32_t JS_STR_PARM_LEN_LIMIT = 1024 * 10; // 10k
41 constexpr uint32_t BUF_SIZE = 1024 * 11; // 11k
42 constexpr int SYS_EVENT_INFO_PARAM_INDEX = 0;
43 constexpr long long DEFAULT_TIME_STAMP = -1;
44 constexpr long long DEFAULT_SEQ = 0;
45 constexpr int32_t DEFAULT_MAX_EVENTS = 1000;
46 constexpr char PARAMS_ATTR[] = "params";
47 constexpr char TAG_ATTR[] = "tag";
48 constexpr char RULE_TYPE_ATTR[] = "ruleType";
49 constexpr char BEGIN_TIME_ATTR[] = "beginTime";
50 constexpr char END_TIME_ATTR[] = "endTime";
51 constexpr char MAX_EVENTS_ATTR[] = "maxEvents";
52 constexpr char BEGIN_SEQ_ATTR[] = "fromSeq";
53 constexpr char END_SEQ_ATTR[] = "toSeq";
54 constexpr char NAMES_ATTR[] = "names";
55 constexpr char CONDITION_ATTR[] = "condition";
56 constexpr char DOMAIN__KEY[] = "domain_";
57 constexpr char NAME__KEY[] = "name_";
58 constexpr char TYPE__KEY[] = "type_";
59 constexpr char INVALID_DOMAIN_DES[] = "Invalid domain name. Possible causes are the specified event domain name does "
60 "not comply with the following rules: 1. Contains only digits, letters, and underscores (_); "
61 "2. Starts with a letter; "
62 "3. Is not empty and contains a maximum of 16 characters.";
63 constexpr char INVALID_NAME_DES[] = "Invalid event name. Possible causes are the specified event name does not "
64 "comply with the following rules: 1. Contains only digits, letters, and underscores (_); "
65 "2. Starts with a letter; "
66 "3. Is not empty and contains a maximum of 32 characters.";
67 constexpr char INVALID_PARAM_NAME_DES[] = "Invalid parameter name. Possible causes are the specified event parameter "
68 "name does not comply with the following rules: 1. Contains only digits, letters, and underscores (_); "
69 "2. Starts with a letter; "
70 "3. Is not empty and contains a maximum of 48 characters.";
71 constexpr char INVALID_QUERY_RULE_DES[] = "Invalid query rule. Possible causes: "
72 "1. The event domain name in the query rule contains more than 16 characters or the event name contains more "
73 "than 32 characters; 2. The event domain name or event name in the query rule contains special characters; "
74 "3. The event domain name or event name in the query rule is empty.";
75 using I64ParseResult = std::pair<bool, int64_t>;
76 using U64ParseResult = std::pair<bool, uint64_t>;
77 using ParsedItem = std::variant<uint64_t, int64_t, double>;
78 enum ParsedItemIndex {
79 U64_INDEX = 0,
80 I64_INDEX,
81 DOUBLE_INDEX,
82 };
83
84 enum ArrayParseStatus {
85 AS_U64_ARR,
86 AS_I64_ARR,
87 AS_DOUBLE_ARR,
88 };
89
90 const std::string INVALID_KEY_TYPE_ARR[] = {
91 "[object Object]",
92 "null",
93 "()",
94 ","
95 };
96
97 template<typename T>
AppendParamsToEventInfo(std::vector<ParsedItem> & src,HiSysEventInfo & info,const std::string & key)98 void AppendParamsToEventInfo(std::vector<ParsedItem>& src,
99 HiSysEventInfo& info, const std::string& key)
100 {
101 std::vector<std::decay_t<T>> dest;
102 for (auto& item : src) {
103 if (item.index() == U64_INDEX) {
104 dest.emplace_back(static_cast<std::decay_t<T>>(std::get<U64_INDEX>(item)));
105 } else if (item.index() == I64_INDEX) {
106 dest.emplace_back(static_cast<std::decay_t<T>>(std::get<I64_INDEX>(item)));
107 } else {
108 dest.emplace_back(static_cast<std::decay_t<T>>(std::get<DOUBLE_INDEX>(item)));
109 }
110 }
111 info.params[key] = dest;
112 }
113
CheckKeyTypeString(const std::string & str)114 bool CheckKeyTypeString(const std::string& str)
115 {
116 bool ret = true;
117 for (auto invalidType : INVALID_KEY_TYPE_ARR) {
118 if (str.find(invalidType) != std::string::npos) {
119 ret = false;
120 break;
121 }
122 }
123 return ret;
124 }
125
IsFloatingNumber(double originalVal)126 bool IsFloatingNumber(double originalVal)
127 {
128 int64_t i64Val = static_cast<int64_t>(originalVal);
129 double i64ToDVal = static_cast<double>(i64Val);
130 return fabs(i64ToDVal - originalVal) > 1e-9; // a minumum value
131 }
132
GetValueType(const napi_env env,const napi_value & value)133 napi_valuetype GetValueType(const napi_env env, const napi_value& value)
134 {
135 napi_valuetype valueType = napi_undefined;
136 napi_status ret = napi_typeof(env, value, &valueType);
137 if (ret != napi_ok) {
138 HILOG_ERROR(LOG_CORE, "failed to parse the type of napi value.");
139 }
140 return valueType;
141 }
142
IsValueTypeValid(const napi_env env,const napi_value & jsObj,const napi_valuetype typeName)143 bool IsValueTypeValid(const napi_env env, const napi_value& jsObj,
144 const napi_valuetype typeName)
145 {
146 napi_valuetype valueType = GetValueType(env, jsObj);
147 if (valueType != typeName) {
148 HILOG_DEBUG(LOG_CORE, "napi value type not match: valueType=%{public}d, typeName=%{public}d.",
149 valueType, typeName);
150 return false;
151 }
152 return true;
153 }
154
CheckValueIsArray(const napi_env env,const napi_value & jsObj)155 bool CheckValueIsArray(const napi_env env, const napi_value& jsObj)
156 {
157 if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
158 return false;
159 }
160 bool isArray = false;
161 napi_status ret = napi_is_array(env, jsObj, &isArray);
162 if (ret != napi_ok) {
163 HILOG_ERROR(LOG_CORE, "failed to check array napi value.");
164 }
165 return isArray;
166 }
167
ParseBoolValue(const napi_env env,const napi_value & value,bool defalutValue=false)168 bool ParseBoolValue(const napi_env env, const napi_value& value, bool defalutValue = false)
169 {
170 bool boolValue = defalutValue;
171 napi_status ret = napi_get_value_bool(env, value, &boolValue);
172 if (ret != napi_ok) {
173 HILOG_ERROR(LOG_CORE, "failed to parse napi value of boolean type.");
174 }
175 return boolValue;
176 }
177
ParseNumberValue(const napi_env env,const napi_value & value,double defaultValue=0.0)178 double ParseNumberValue(const napi_env env, const napi_value& value, double defaultValue = 0.0)
179 {
180 double numValue = defaultValue;
181 napi_status ret = napi_get_value_double(env, value, &numValue);
182 if (ret != napi_ok) {
183 HILOG_ERROR(LOG_CORE, "failed to parse napi value of number type.");
184 }
185 return numValue;
186 }
187
ParseStringValue(const napi_env env,const napi_value & value,std::string defaultValue="")188 std::string ParseStringValue(const napi_env env, const napi_value& value, std::string defaultValue = "")
189 {
190 char buf[BUF_SIZE] = {0};
191 size_t bufLength = 0;
192 napi_status status = napi_get_value_string_utf8(env, value, buf, BUF_SIZE - 1, &bufLength);
193 if (status != napi_ok) {
194 HILOG_DEBUG(LOG_CORE, "failed to parse napi value of string type.");
195 return defaultValue;
196 }
197 std::string dest = std::string {buf};
198 return dest;
199 }
200
ParseSignedBigIntValue(const napi_env env,const napi_value & value)201 I64ParseResult ParseSignedBigIntValue(const napi_env env, const napi_value& value)
202 {
203 I64ParseResult ret = std::make_pair(false, 0); // default result
204 int64_t val = 0;
205 bool lossless = true;
206 napi_status status = napi_get_value_bigint_int64(env, value, &val, &lossless);
207 if (status != napi_ok) {
208 HILOG_DEBUG(LOG_CORE, "failed to parse int64_t number.");
209 return ret;
210 }
211 ret.first = lossless;
212 ret.second = val;
213 return ret;
214 }
215
ParseUnsignedBigIntValue(const napi_env env,const napi_value & value)216 U64ParseResult ParseUnsignedBigIntValue(const napi_env env, const napi_value& value)
217 {
218 U64ParseResult ret = std::make_pair(false, 0); // default result
219 uint64_t val = 0;
220 bool lossless = true;
221 napi_status status = napi_get_value_bigint_uint64(env, value, &val, &lossless);
222 if (status != napi_ok) {
223 HILOG_DEBUG(LOG_CORE, "failed to parse uint64_t number.");
224 return ret;
225 }
226 ret.first = lossless;
227 ret.second = val;
228 return ret;
229 }
230
ParseBigIntResultValue(const napi_env env,const napi_value & value,U64ParseResult & u64Ret,I64ParseResult & i64Ret)231 void ParseBigIntResultValue(const napi_env env, const napi_value& value, U64ParseResult& u64Ret,
232 I64ParseResult& i64Ret)
233 {
234 u64Ret = ParseUnsignedBigIntValue(env, value);
235 if (!u64Ret.first) {
236 i64Ret = ParseSignedBigIntValue(env, value);
237 }
238 }
239
GetTagAttribute(const napi_env env,const napi_value & object,std::string defaultValue="")240 std::string GetTagAttribute(const napi_env env, const napi_value& object, std::string defaultValue = "")
241 {
242 napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, TAG_ATTR);
243 if (IsValueTypeValid(env, propertyValue, napi_valuetype::napi_null) ||
244 IsValueTypeValid(env, propertyValue, napi_valuetype::napi_undefined)) {
245 return defaultValue;
246 }
247 if (IsValueTypeValid(env, propertyValue, napi_valuetype::napi_string)) {
248 return ParseStringValue(env, propertyValue, defaultValue);
249 }
250 NapiHiSysEventUtil::ThrowParamTypeError(env, TAG_ATTR, "string");
251 HILOG_ERROR(LOG_CORE, "type of listener tag is not napi_string.");
252 return defaultValue;
253 }
254
GetStringTypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,std::string defaultValue="")255 std::string GetStringTypeAttribute(const napi_env env, const napi_value& object,
256 const std::string& propertyName, std::string defaultValue = "")
257 {
258 napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
259 if (!IsValueTypeValid(env, propertyValue, napi_valuetype::napi_string)) {
260 NapiHiSysEventUtil::ThrowParamTypeError(env, propertyName, "string");
261 HILOG_DEBUG(LOG_CORE, "type is not napi_string.");
262 return defaultValue;
263 }
264 return ParseStringValue(env, propertyValue, defaultValue);
265 }
266
GetLonglongTypeAttribute(const napi_env env,const napi_value & val,long long defaultValue=0)267 long long GetLonglongTypeAttribute(const napi_env env, const napi_value& val, long long defaultValue = 0)
268 {
269 bool isNumberType = IsValueTypeValid(env, val, napi_valuetype::napi_number);
270 bool isBigIntType = IsValueTypeValid(env, val, napi_valuetype::napi_bigint);
271 if (!isNumberType && !isBigIntType) {
272 HILOG_DEBUG(LOG_CORE, "type is not napi_number or napi_bigint.");
273 return defaultValue;
274 }
275 if (isNumberType) {
276 return static_cast<long long>(ParseNumberValue(env, val, defaultValue));
277 }
278 I64ParseResult ret = ParseSignedBigIntValue(env, val);
279 return static_cast<long long>(ret.second);
280 }
281
ParseInt32Value(const napi_env env,const napi_value & value,int32_t defaultValue=0)282 int32_t ParseInt32Value(const napi_env env, const napi_value& value, int32_t defaultValue = 0)
283 {
284 int32_t int32Value = 0;
285 napi_status ret = napi_get_value_int32(env, value, &int32Value);
286 if (ret != napi_ok) {
287 HILOG_DEBUG(LOG_CORE, "failed to parse napi value of number type.");
288 return defaultValue;
289 }
290 return int32Value;
291 }
292
GetInt32TypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,int32_t defaultValue=0)293 int32_t GetInt32TypeAttribute(const napi_env env, const napi_value& object,
294 const std::string& propertyName, int32_t defaultValue = 0)
295 {
296 napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
297 if (!IsValueTypeValid(env, propertyValue, napi_valuetype::napi_number)) {
298 NapiHiSysEventUtil::ThrowParamTypeError(env, propertyName, "number");
299 HILOG_DEBUG(LOG_CORE, "type is not napi_number.");
300 return defaultValue;
301 }
302 return ParseInt32Value(env, propertyValue);
303 }
304
AppendBoolArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)305 void AppendBoolArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
306 const napi_value array, size_t len)
307 {
308 std::vector<bool> values;
309 napi_value element;
310 napi_status status;
311 for (uint32_t i = 0; i < len; i++) {
312 status = napi_get_element(env, array, i, &element);
313 if (status != napi_ok) {
314 HILOG_ERROR(LOG_CORE, "failed to get the element of bool array.");
315 continue;
316 }
317 if (IsValueTypeValid(env, element, napi_valuetype::napi_boolean)) {
318 values.emplace_back(ParseBoolValue(env, element));
319 }
320 }
321 info.params[key] = values;
322 }
323
AppendNumberArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)324 void AppendNumberArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
325 const napi_value array, size_t len)
326 {
327 std::vector<ParsedItem> parsedArray;
328 ArrayParseStatus pStatus = AS_U64_ARR;
329 double parsedVal = 0;
330 napi_value element;
331 napi_status status;
332 for (uint32_t i = 0; i < len; i++) {
333 status = napi_get_element(env, array, i, &element);
334 if (status != napi_ok || !IsValueTypeValid(env, element, napi_valuetype::napi_number)) {
335 HILOG_ERROR(LOG_CORE,
336 "failed to get the element from array or type not match.");
337 continue;
338 }
339 parsedVal = ParseNumberValue(env, element);
340 if (IsFloatingNumber(parsedVal)) {
341 pStatus = AS_DOUBLE_ARR;
342 parsedArray.emplace_back(parsedVal);
343 continue;
344 }
345 if (parsedVal < 0 && pStatus != AS_DOUBLE_ARR) {
346 pStatus = AS_I64_ARR;
347 parsedArray.emplace_back(static_cast<int64_t>(parsedVal));
348 continue;
349 }
350 parsedArray.emplace_back(static_cast<uint64_t>(parsedVal));
351 }
352 if (pStatus == AS_DOUBLE_ARR) {
353 AppendParamsToEventInfo<double>(parsedArray, info, key);
354 } else if (pStatus == AS_I64_ARR) {
355 AppendParamsToEventInfo<int64_t>(parsedArray, info, key);
356 } else {
357 AppendParamsToEventInfo<uint64_t>(parsedArray, info, key);
358 }
359 }
360
AppendBigIntArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)361 void AppendBigIntArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
362 const napi_value array, size_t len)
363 {
364 std::vector<ParsedItem> parsedArray;
365 ArrayParseStatus pStatus = AS_U64_ARR;
366 napi_value element;
367 napi_status status;
368 U64ParseResult u64Ret = std::make_pair(false, 0); //default value
369 I64ParseResult i64Ret = std::make_pair(false, 0); //default value
370 for (uint32_t i = 0; i < len; i++) {
371 status = napi_get_element(env, array, i, &element);
372 if (status != napi_ok || !IsValueTypeValid(env, element, napi_valuetype::napi_bigint)) {
373 HILOG_ERROR(LOG_CORE,
374 "failed to get the element from array or type not match.");
375 continue;
376 }
377 ParseBigIntResultValue(env, element, u64Ret, i64Ret);
378 if (u64Ret.first) {
379 parsedArray.emplace_back(u64Ret.second);
380 continue;
381 }
382 pStatus = AS_I64_ARR;
383 parsedArray.emplace_back(i64Ret.second);
384 }
385 if (pStatus == AS_I64_ARR) {
386 AppendParamsToEventInfo<int64_t>(parsedArray, info, key);
387 return;
388 }
389 AppendParamsToEventInfo<uint64_t>(parsedArray, info, key);
390 }
391
AppendStringArrayData(const napi_env env,HiSysEventInfo & info,const std::string & key,const napi_value array,size_t len)392 void AppendStringArrayData(const napi_env env, HiSysEventInfo& info, const std::string& key,
393 const napi_value array, size_t len)
394 {
395 std::vector<std::string> values;
396 napi_value element;
397 napi_status status;
398 for (uint32_t i = 0; i < len; i++) {
399 status = napi_get_element(env, array, i, &element);
400 if (status != napi_ok) {
401 HILOG_ERROR(LOG_CORE, "failed to get the element of string array.");
402 continue;
403 }
404 if (IsValueTypeValid(env, element, napi_valuetype::napi_string)) {
405 values.emplace_back(ParseStringValue(env, element));
406 }
407 }
408 info.params[key] = values;
409 }
410
AddArrayParamToEventInfo(const napi_env env,HiSysEventInfo & info,const std::string & key,napi_value & array)411 void AddArrayParamToEventInfo(const napi_env env, HiSysEventInfo& info, const std::string& key, napi_value& array)
412 {
413 uint32_t len = 0;
414 napi_status status = napi_get_array_length(env, array, &len);
415 if (status != napi_ok) {
416 HILOG_ERROR(LOG_CORE, "failed to get the length of param array.");
417 return;
418 }
419 if (len == 0) {
420 HILOG_WARN(LOG_CORE, "array is empty.");
421 return;
422 }
423 napi_value firstItem;
424 status = napi_get_element(env, array, 0, &firstItem);
425 if (status != napi_ok) {
426 HILOG_ERROR(LOG_CORE, "failed to get the first element in array.");
427 return;
428 }
429 napi_valuetype type;
430 status = napi_typeof(env, firstItem, &type);
431 if (status != napi_ok) {
432 HILOG_ERROR(LOG_CORE, "failed to get the type of the first element in array.");
433 return;
434 }
435 switch (type) {
436 case napi_valuetype::napi_boolean:
437 AppendBoolArrayData(env, info, key, array, len);
438 HILOG_DEBUG(LOG_CORE, "AppendBoolArrayData: %{public}s.", key.c_str());
439 break;
440 case napi_valuetype::napi_number:
441 AppendNumberArrayData(env, info, key, array, len);
442 HILOG_DEBUG(LOG_CORE, "AppendNumberArrayData: %{public}s.", key.c_str());
443 break;
444 case napi_valuetype::napi_bigint:
445 AppendBigIntArrayData(env, info, key, array, len);
446 HILOG_DEBUG(LOG_CORE, "AppendBigIntArrayData: %{public}s.", key.c_str());
447 break;
448 case napi_valuetype::napi_string:
449 AppendStringArrayData(env, info, key, array, len);
450 HILOG_DEBUG(LOG_CORE, "AppendStringArrayData: %{public}s.", key.c_str());
451 break;
452 default:
453 break;
454 }
455 }
456
AddParamToEventInfo(const napi_env env,HiSysEventInfo & info,const std::string & key,napi_value & value)457 void AddParamToEventInfo(const napi_env env, HiSysEventInfo& info, const std::string& key, napi_value& value)
458 {
459 if (CheckValueIsArray(env, value)) {
460 AddArrayParamToEventInfo(env, info, key, value);
461 return;
462 }
463 napi_valuetype type = GetValueType(env, value);
464 double parsedVal = 0;
465 U64ParseResult u64Ret = std::make_pair(false, 0); //default value
466 I64ParseResult i64Ret = std::make_pair(false, 0); //default value
467 switch (type) {
468 case napi_valuetype::napi_boolean:
469 HILOG_DEBUG(LOG_CORE, "AddBoolParamToEventInfo: %{public}s.", key.c_str());
470 info.params[key] = ParseBoolValue(env, value);
471 break;
472 case napi_valuetype::napi_number:
473 HILOG_DEBUG(LOG_CORE, "AddNumberParamToEventInfo: %{public}s.", key.c_str());
474 parsedVal = ParseNumberValue(env, value);
475 if (IsFloatingNumber(parsedVal)) {
476 info.params[key] = parsedVal;
477 } else if (parsedVal < 0) {
478 info.params[key] = static_cast<int64_t>(parsedVal);
479 } else {
480 info.params[key] = static_cast<uint64_t>(parsedVal);
481 }
482 break;
483 case napi_valuetype::napi_string:
484 HILOG_DEBUG(LOG_CORE, "AddStringParamToEventInfo: %{public}s.", key.c_str());
485 info.params[key] = ParseStringValue(env, value);
486 break;
487 case napi_valuetype::napi_bigint:
488 HILOG_DEBUG(LOG_CORE, "AddBigIntParamToEventInfo: %{public}s.", key.c_str());
489 ParseBigIntResultValue(env, value, u64Ret, i64Ret);
490 if (u64Ret.first) {
491 info.params[key] = u64Ret.second;
492 } else {
493 info.params[key] = i64Ret.second;
494 }
495 break;
496 default:
497 break;
498 }
499 }
500
GetObjectTypeAttribute(const napi_env env,const napi_value & object,const std::string & propertyName,HiSysEventInfo & info)501 void GetObjectTypeAttribute(const napi_env env, const napi_value& object,
502 const std::string& propertyName, HiSysEventInfo& info)
503 {
504 napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, object, propertyName);
505 if (!IsValueTypeValid(env, propertyValue, napi_valuetype::napi_object)) {
506 HILOG_DEBUG(LOG_CORE, "type is not napi_object.");
507 return;
508 }
509 napi_value keyArr = nullptr;
510 napi_status status = napi_get_property_names(env, propertyValue, &keyArr);
511 if (status != napi_ok) {
512 HILOG_ERROR(LOG_CORE, "failed to parse property names of a js object.");
513 return;
514 }
515 uint32_t len = 0;
516 status = napi_get_array_length(env, keyArr, &len);
517 if (status != napi_ok) {
518 HILOG_ERROR(LOG_CORE, "failed to get the length of the key-value pairs.");
519 return;
520 }
521 for (uint32_t i = 0; i < len; i++) {
522 napi_value key = nullptr;
523 napi_get_element(env, keyArr, i, &key);
524 if (!IsValueTypeValid(env, key, napi_valuetype::napi_string)) {
525 HILOG_WARN(LOG_CORE, "this param would be discarded because of invalid type of the key.");
526 continue;
527 }
528 char buf[BUF_SIZE] = {0};
529 size_t valueLen = 0;
530 napi_get_value_string_utf8(env, key, buf, BUF_SIZE - 1, &valueLen);
531 if (!CheckKeyTypeString(buf)) {
532 HILOG_WARN(LOG_CORE, "this param would be discarded because of invalid format of the key.");
533 continue;
534 }
535 napi_value val = NapiHiSysEventUtil::GetPropertyByName(env, propertyValue, buf);
536 AddParamToEventInfo(env, info, buf, val);
537 }
538 }
539
ParseStringArray(const napi_env env,napi_value & arrayValue,std::vector<std::string> & arrayDest)540 void ParseStringArray(const napi_env env, napi_value& arrayValue, std::vector<std::string>& arrayDest)
541 {
542 if (!CheckValueIsArray(env, arrayValue)) {
543 HILOG_ERROR(LOG_CORE, "try to parse a array from a napi value without array type");
544 return;
545 }
546 uint32_t len = 0;
547 napi_status status = napi_get_array_length(env, arrayValue, &len);
548 if (status != napi_ok) {
549 return;
550 }
551 napi_value element;
552 for (uint32_t i = 0; i < len; i++) {
553 status = napi_get_element(env, arrayValue, i, &element);
554 if (status != napi_ok) {
555 return;
556 }
557 if (IsValueTypeValid(env, element, napi_valuetype::napi_string)) {
558 std::string str = ParseStringValue(env, element);
559 arrayDest.emplace_back(str);
560 }
561 }
562 }
563
ParseListenerRule(const napi_env env,const napi_value & jsObj)564 ListenerRule ParseListenerRule(const napi_env env, const napi_value& jsObj)
565 {
566 if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
567 return ListenerRule("", RuleType::WHOLE_WORD);
568 }
569 std::string domain = GetStringTypeAttribute(env, jsObj, NapiHiSysEventUtil::DOMAIN_ATTR);
570 HILOG_DEBUG(LOG_CORE, "domain is %{public}s.", domain.c_str());
571 std::string name = GetStringTypeAttribute(env, jsObj, NapiHiSysEventUtil::NAME_ATTR);
572 HILOG_DEBUG(LOG_CORE, "name is %{public}s.", name.c_str());
573 int32_t ruleType = GetInt32TypeAttribute(env, jsObj, RULE_TYPE_ATTR, RuleType::WHOLE_WORD);
574 HILOG_DEBUG(LOG_CORE, "ruleType is %{public}d.", ruleType);
575 std::string tag = GetTagAttribute(env, jsObj);
576 HILOG_DEBUG(LOG_CORE, "tag is %{public}s.", tag.c_str());
577 return ListenerRule(domain, name, tag, RuleType(ruleType));
578 }
579
IsQueryRuleValid(const napi_env env,const QueryRule & rule)580 bool IsQueryRuleValid(const napi_env env, const QueryRule& rule)
581 {
582 auto domain = rule.GetDomain();
583 if (!StringFilter::GetInstance().IsValidName(domain, MAX_DOMAIN_LENGTH)) {
584 NapiHiSysEventUtil::ThrowErrorByRet(env, NapiInnerError::ERR_INVALID_DOMAIN_IN_QUERY_RULE);
585 return false;
586 }
587 auto names = rule.GetEventList();
588 if (std::any_of(names.begin(), names.end(), [] (auto& name) {
589 return !StringFilter::GetInstance().IsValidName(name, MAX_EVENT_NAME_LENGTH);
590 })) {
591 NapiHiSysEventUtil::ThrowErrorByRet(env, NapiInnerError::ERR_INVALID_EVENT_NAME_IN_QUERY_RULE);
592 return false;
593 }
594 return true;
595 }
596
ParseQueryRule(const napi_env env,napi_value & jsObj)597 QueryRule ParseQueryRule(const napi_env env, napi_value& jsObj)
598 {
599 std::vector<std::string> names;
600 if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
601 return QueryRule("", names);
602 }
603 std::string domain = GetStringTypeAttribute(env, jsObj, NapiHiSysEventUtil::DOMAIN_ATTR);
604 HILOG_DEBUG(LOG_CORE, "domain is %{public}s.", domain.c_str());
605 napi_value propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, NAMES_ATTR);
606 ParseStringArray(env, propertyValue, names);
607 propertyValue = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, CONDITION_ATTR);
608 std::string condition = ParseStringValue(env, propertyValue);
609 HILOG_DEBUG(LOG_CORE, "condition is %{public}s.", condition.c_str());
610 return QueryRule(domain, names, RuleType::WHOLE_WORD, 0, condition);
611 }
612
SetNamedProperty(const napi_env env,napi_value & object,const std::string & propertyName,napi_value & propertyValue)613 void SetNamedProperty(const napi_env env, napi_value& object, const std::string& propertyName,
614 napi_value& propertyValue)
615 {
616 napi_status status = napi_set_named_property(env, object, propertyName.c_str(), propertyValue);
617 if (status != napi_ok) {
618 HILOG_ERROR(LOG_CORE, "set property %{public}s failed.", propertyName.c_str());
619 }
620 }
621
IsBaseInfoKey(const std::string & propertyName)622 bool IsBaseInfoKey(const std::string& propertyName)
623 {
624 return propertyName == DOMAIN__KEY || propertyName == NAME__KEY || propertyName == TYPE__KEY;
625 }
626
TranslateKeyToAttrName(const std::string & key)627 std::string TranslateKeyToAttrName(const std::string& key)
628 {
629 if (key == DOMAIN__KEY) {
630 return NapiHiSysEventUtil::DOMAIN_ATTR;
631 }
632 if (key == NAME__KEY) {
633 return NapiHiSysEventUtil::NAME_ATTR;
634 }
635 if (key == TYPE__KEY) {
636 return NapiHiSysEventUtil::EVENT_TYPE_ATTR;
637 }
638 return "";
639 }
640
AppendBaseInfo(const napi_env env,napi_value & sysEventInfo,const std::string & key,Json::Value & value)641 void AppendBaseInfo(const napi_env env, napi_value& sysEventInfo, const std::string& key, Json::Value& value)
642 {
643 if ((key == DOMAIN__KEY || key == NAME__KEY) && value.isString()) {
644 NapiHiSysEventUtil::AppendStringPropertyToJsObject(env, TranslateKeyToAttrName(key),
645 value.asString(), sysEventInfo);
646 }
647 if (key == TYPE__KEY && value.isInt()) {
648 NapiHiSysEventUtil::AppendInt32PropertyToJsObject(env, TranslateKeyToAttrName(key),
649 static_cast<int32_t>(value.asInt()), sysEventInfo);
650 }
651 }
652
CreateBoolValue(const napi_env env,bool value,napi_value & val)653 void CreateBoolValue(const napi_env env, bool value, napi_value& val)
654 {
655 napi_status status = napi_get_boolean(env, value, &val);
656 if (status != napi_ok) {
657 HILOG_ERROR(LOG_CORE, "failed to get create napi value of bool type.");
658 }
659 }
660
CreateDoubleValue(const napi_env env,double value,napi_value & val)661 void CreateDoubleValue(const napi_env env, double value, napi_value& val)
662 {
663 napi_status status = napi_create_double(env, value, &val);
664 if (status != napi_ok) {
665 HILOG_ERROR(LOG_CORE, "failed to get create napi value of double type.");
666 }
667 }
668
CreateUint32Value(const napi_env env,uint32_t value,napi_value & val)669 void CreateUint32Value(const napi_env env, uint32_t value, napi_value& val)
670 {
671 napi_status status = napi_create_uint32(env, value, &val);
672 if (status != napi_ok) {
673 HILOG_ERROR(LOG_CORE, "failed to get create napi value of uint32 type.");
674 }
675 }
676
CreateParamItemTypeValue(const napi_env env,Json::Value & jsonValue,napi_value & value)677 bool CreateParamItemTypeValue(const napi_env env, Json::Value& jsonValue, napi_value& value)
678 {
679 if (jsonValue.isBool()) {
680 CreateBoolValue(env, jsonValue.asBool(), value);
681 return true;
682 }
683 if (jsonValue.isInt()) {
684 NapiHiSysEventUtil::CreateInt32Value(env, static_cast<int32_t>(jsonValue.asInt()), value);
685 return true;
686 }
687 if (jsonValue.isUInt()) {
688 CreateUint32Value(env, static_cast<uint32_t>(jsonValue.asUInt()), value);
689 return true;
690 }
691 #ifdef JSON_HAS_INT64
692 if (jsonValue.isInt64() && jsonValue.type() != Json::ValueType::uintValue) {
693 NapiHiSysEventUtil::CreateInt64Value(env, jsonValue.asInt64(), value);
694 return true;
695 }
696 if (jsonValue.isUInt64() && jsonValue.type() != Json::ValueType::intValue) {
697 NapiHiSysEventUtil::CreateUInt64Value(env, jsonValue.asUInt64(), value);
698 return true;
699 }
700 #endif
701 if (jsonValue.isDouble()) {
702 CreateDoubleValue(env, jsonValue.asDouble(), value);
703 return true;
704 }
705 if (jsonValue.isString()) {
706 NapiHiSysEventUtil::CreateStringValue(env, jsonValue.asString(), value);
707 return true;
708 }
709 return false;
710 }
711
AppendArrayParams(const napi_env env,napi_value & params,const std::string & key,Json::Value & value)712 void AppendArrayParams(const napi_env env, napi_value& params, const std::string& key, Json::Value& value)
713 {
714 size_t len = value.size();
715 napi_value array = nullptr;
716 napi_create_array_with_length(env, len, &array);
717 for (size_t i = 0; i < len; i++) {
718 napi_value item;
719 if (!CreateParamItemTypeValue(env, value[static_cast<int>(i)], item)) {
720 continue;
721 }
722 napi_set_element(env, array, i, item);
723 }
724 SetNamedProperty(env, params, key, array);
725 }
726
AppendParamsInfo(const napi_env env,napi_value & params,const std::string & key,Json::Value & jsonValue)727 void AppendParamsInfo(const napi_env env, napi_value& params, const std::string& key, Json::Value& jsonValue)
728 {
729 if (jsonValue.isArray()) {
730 AppendArrayParams(env, params, key, jsonValue);
731 return;
732 }
733 napi_value property = nullptr;
734 if (!CreateParamItemTypeValue(env, jsonValue, property)) {
735 return;
736 }
737 SetNamedProperty(env, params, key, property);
738 }
739 }
740
GetPropertyByName(const napi_env env,const napi_value & object,const std::string & propertyName)741 napi_value NapiHiSysEventUtil::GetPropertyByName(const napi_env env, const napi_value& object,
742 const std::string& propertyName)
743 {
744 napi_value result = nullptr;
745 napi_status status = napi_get_named_property(env, object, propertyName.c_str(), &result);
746 if (status != napi_ok) {
747 HILOG_DEBUG(LOG_CORE, "failed to parse property named %{public}s from JS object.", propertyName.c_str());
748 }
749 return result;
750 }
751
ParseHiSysEventInfo(const napi_env env,napi_value * param,size_t paramNum,HiSysEventInfo & info)752 void NapiHiSysEventUtil::ParseHiSysEventInfo(const napi_env env, napi_value* param,
753 size_t paramNum, HiSysEventInfo& info)
754 {
755 if (paramNum <= SYS_EVENT_INFO_PARAM_INDEX) {
756 return;
757 }
758 if (!IsValueTypeValid(env, param[SYS_EVENT_INFO_PARAM_INDEX], napi_valuetype::napi_object)) {
759 NapiHiSysEventUtil::ThrowParamTypeError(env, "info", "object");
760 return;
761 }
762 info.domain = GetStringTypeAttribute(env, param[SYS_EVENT_INFO_PARAM_INDEX], NapiHiSysEventUtil::DOMAIN_ATTR);
763 HILOG_DEBUG(LOG_CORE, "domain is %{public}s.", info.domain.c_str());
764 info.name = GetStringTypeAttribute(env, param[SYS_EVENT_INFO_PARAM_INDEX], NapiHiSysEventUtil::NAME_ATTR);
765 HILOG_DEBUG(LOG_CORE, "name is %{public}s.", info.name.c_str());
766 info.eventType = HiSysEvent::EventType(GetInt32TypeAttribute(env,
767 param[SYS_EVENT_INFO_PARAM_INDEX], EVENT_TYPE_ATTR, HiSysEvent::EventType::FAULT));
768 HILOG_DEBUG(LOG_CORE, "eventType is %{public}d.", info.eventType);
769 GetObjectTypeAttribute(env, param[SYS_EVENT_INFO_PARAM_INDEX], PARAMS_ATTR, info);
770 }
771
HasStrParamLenOverLimit(HiSysEventInfo & info)772 bool NapiHiSysEventUtil::HasStrParamLenOverLimit(HiSysEventInfo& info)
773 {
774 return any_of(info.params.begin(), info.params.end(), [] (auto& item) {
775 if (item.second.index() != STR && item.second.index() != STR_ARR) {
776 return false;
777 }
778 if (item.second.index() == STR) {
779 return std::get<STR>(item.second).size() > JS_STR_PARM_LEN_LIMIT;
780 }
781 auto allStr = std::get<STR_ARR>(item.second);
782 return any_of(allStr.begin(), allStr.end(), [] (auto& item) {
783 return item.size() > JS_STR_PARM_LEN_LIMIT;
784 });
785 });
786 }
787
CreateHiSysEventInfoJsObject(const napi_env env,const std::string & jsonStr,napi_value & sysEventInfo)788 void NapiHiSysEventUtil::CreateHiSysEventInfoJsObject(const napi_env env, const std::string& jsonStr,
789 napi_value& sysEventInfo)
790 {
791 Json::Value eventJson;
792 #ifdef JSONCPP_VERSION_STRING
793 Json::CharReaderBuilder jsonRBuilder;
794 Json::CharReaderBuilder::strictMode(&jsonRBuilder.settings_);
795 std::unique_ptr<Json::CharReader> const reader(jsonRBuilder.newCharReader());
796 JSONCPP_STRING errs;
797 if (!reader->parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), &eventJson, &errs)) {
798 #else
799 Json::Reader reader(Json::Features::strictMode());
800 if (!reader.parse(jsonStr, eventJson)) {
801 #endif
802 HILOG_ERROR(LOG_CORE, "parse event detail info failed, please check the style of json infomation: %{public}s",
803 jsonStr.c_str());
804 return;
805 }
806 if (!eventJson.isObject()) {
807 HILOG_ERROR(LOG_CORE, "event json parsed isn't a json object");
808 return;
809 }
810 napi_create_object(env, &sysEventInfo);
811 napi_value params = nullptr;
812 napi_create_object(env, ¶ms);
813 auto eventNameList = eventJson.getMemberNames();
814 for (auto it = eventNameList.cbegin(); it != eventNameList.cend(); it++) {
815 auto propertyName = *it;
816 if (IsBaseInfoKey(propertyName)) {
817 AppendBaseInfo(env, sysEventInfo, propertyName, eventJson[propertyName]);
818 } else {
819 AppendParamsInfo(env, params, propertyName, eventJson[propertyName]);
820 }
821 }
822 SetNamedProperty(env, sysEventInfo, PARAMS_ATTR, params);
823 }
824
825 void NapiHiSysEventUtil::CreateJsSysEventInfoArray(const napi_env env, const std::vector<std::string>& originValues,
826 napi_value& array)
827 {
828 auto len = originValues.size();
829 for (size_t i = 0; i < len; i++) {
830 napi_value item;
831 CreateHiSysEventInfoJsObject(env, originValues[i], item);
832 napi_status status = napi_set_element(env, array, i, item);
833 if (status != napi_ok) {
834 HILOG_DEBUG(LOG_CORE, "napi_set_element failed");
835 }
836 }
837 }
838
839 void NapiHiSysEventUtil::AppendStringPropertyToJsObject(const napi_env env, const std::string& key,
840 const std::string& value, napi_value& jsObj)
841 {
842 napi_value property = nullptr;
843 NapiHiSysEventUtil::CreateStringValue(env, value, property);
844 SetNamedProperty(env, jsObj, key, property);
845 }
846
847 void NapiHiSysEventUtil::AppendInt32PropertyToJsObject(const napi_env env, const std::string& key,
848 const int32_t& value, napi_value& jsObj)
849 {
850 napi_value property = nullptr;
851 NapiHiSysEventUtil::CreateInt32Value(env, value, property);
852 SetNamedProperty(env, jsObj, key, property);
853 }
854
855 int32_t NapiHiSysEventUtil::ParseListenerRules(const napi_env env, napi_value& array,
856 std::vector<ListenerRule>& listenerRules)
857 {
858 if (!CheckValueIsArray(env, array)) {
859 ThrowParamTypeError(env, "rules", "array");
860 return ERR_LISTENER_RULES_TYPE_NOT_ARRAY;
861 }
862 uint32_t len = 0;
863 napi_status status = napi_get_array_length(env, array, &len);
864 if (status != napi_ok) {
865 return ERR_NAPI_PARSED_FAILED;
866 }
867 napi_value firstItem;
868 status = napi_get_element(env, array, 0, &firstItem);
869 if (status != napi_ok) {
870 return ERR_NAPI_PARSED_FAILED;
871 }
872 napi_valuetype type;
873 status = napi_typeof(env, firstItem, &type);
874 if (status != napi_ok) {
875 return ERR_NAPI_PARSED_FAILED;
876 }
877 napi_value element;
878 for (uint32_t i = 0; i < len; i++) {
879 status = napi_get_element(env, array, i, &element);
880 if (status != napi_ok) {
881 return ERR_NAPI_PARSED_FAILED;
882 }
883 if (IsValueTypeValid(env, element, napi_valuetype::napi_object)) {
884 listenerRules.emplace_back(ParseListenerRule(env, element));
885 }
886 }
887 return NAPI_SUCCESS;
888 }
889
890 int32_t NapiHiSysEventUtil::ParseQueryRules(const napi_env env, napi_value& array, std::vector<QueryRule>& queryRules)
891 {
892 if (!CheckValueIsArray(env, array)) {
893 ThrowParamTypeError(env, "rules", "array");
894 return ERR_QUERY_RULES_TYPE_NOT_ARRAY;
895 }
896 uint32_t len = 0;
897 napi_status status = napi_get_array_length(env, array, &len);
898 if (status != napi_ok) {
899 return ERR_NAPI_PARSED_FAILED;
900 }
901 napi_value firstItem;
902 status = napi_get_element(env, array, 0, &firstItem);
903 if (status != napi_ok) {
904 return ERR_NAPI_PARSED_FAILED;
905 }
906 napi_valuetype type;
907 status = napi_typeof(env, firstItem, &type);
908 if (status != napi_ok) {
909 return ERR_NAPI_PARSED_FAILED;
910 }
911 napi_value element;
912 for (uint32_t i = 0; i < len; i++) {
913 status = napi_get_element(env, array, i, &element);
914 if (status != napi_ok) {
915 return ERR_NAPI_PARSED_FAILED;
916 }
917 if (IsValueTypeValid(env, element, napi_valuetype::napi_object)) {
918 auto queryRule = ParseQueryRule(env, element);
919 if (IsQueryRuleValid(env, queryRule)) {
920 queryRules.emplace_back(queryRule);
921 }
922 }
923 }
924 return NAPI_SUCCESS;
925 }
926
927 int32_t NapiHiSysEventUtil::ParseQueryArg(const napi_env env, napi_value& jsObj, QueryArg& queryArg)
928 {
929 if (!IsValueTypeValid(env, jsObj, napi_valuetype::napi_object)) {
930 ThrowParamTypeError(env, "queryArg", "object");
931 return ERR_QUERY_ARG_TYPE_INVALID;
932 }
933 auto beginTimeVal = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, BEGIN_TIME_ATTR);
934 auto endTimeVal = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, END_TIME_ATTR);
935 auto fromSeqVal = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, BEGIN_SEQ_ATTR);
936 auto toSeqVal = NapiHiSysEventUtil::GetPropertyByName(env, jsObj, END_SEQ_ATTR);
937 if ((IsNullOrUndefined(env, beginTimeVal) || IsNullOrUndefined(env, endTimeVal)) &&
938 (IsNullOrUndefined(env, fromSeqVal) || IsNullOrUndefined(env, toSeqVal))) {
939 ThrowParamTypeError(env, "queryArg's member", "not null or undefined");
940 return ERR_QUERY_ARG_TYPE_INVALID;
941 }
942
943 auto beginTime = GetLonglongTypeAttribute(env, beginTimeVal, DEFAULT_TIME_STAMP);
944 queryArg.beginTime = beginTime < 0 ? 0 : beginTime;
945 auto endTime = GetLonglongTypeAttribute(env, endTimeVal, DEFAULT_TIME_STAMP);
946 queryArg.endTime = endTime < 0 ? std::numeric_limits<long long>::max() : endTime;
947 queryArg.fromSeq = GetLonglongTypeAttribute(env, fromSeqVal, DEFAULT_SEQ);
948 queryArg.toSeq = GetLonglongTypeAttribute(env, toSeqVal, DEFAULT_SEQ);
949
950 auto maxEvents = GetInt32TypeAttribute(env, jsObj, MAX_EVENTS_ATTR, DEFAULT_MAX_EVENTS);
951 queryArg.maxEvents = maxEvents < 0 ? std::numeric_limits<int>::max() : maxEvents;
952
953 return NAPI_SUCCESS;
954 }
955
956 void NapiHiSysEventUtil::CreateNull(const napi_env env, napi_value& ret)
957 {
958 napi_status status = napi_get_null(env, &ret);
959 if (status != napi_ok) {
960 HILOG_ERROR(LOG_CORE, "failed to create napi value of null.");
961 }
962 }
963
964 void NapiHiSysEventUtil::CreateInt32Value(const napi_env env, int32_t value, napi_value& ret)
965 {
966 napi_status status = napi_create_int32(env, value, &ret);
967 if (status != napi_ok) {
968 HILOG_ERROR(LOG_CORE, "failed to create napi value of int32 type.");
969 }
970 }
971
972 void NapiHiSysEventUtil::CreateInt64Value(const napi_env env, int64_t value, napi_value& ret)
973 {
974 napi_status status = napi_create_bigint_int64(env, value, &ret);
975 if (status != napi_ok) {
976 HILOG_ERROR(LOG_CORE, "failed to create napi value of int64_t type.");
977 }
978 }
979
980 void NapiHiSysEventUtil::CreateUInt64Value(const napi_env env, uint64_t value, napi_value& ret)
981 {
982 napi_status status = napi_create_bigint_uint64(env, value, &ret);
983 if (status != napi_ok) {
984 HILOG_ERROR(LOG_CORE, "failed to create napi value of uint64_t type.");
985 }
986 }
987
988 void NapiHiSysEventUtil::CreateStringValue(const napi_env env, std::string value, napi_value& ret)
989 {
990 napi_status status = napi_create_string_utf8(env, value.c_str(), NAPI_AUTO_LENGTH, &ret);
991 if (status != napi_ok) {
992 HILOG_ERROR(LOG_CORE, "failed to create napi value of string type.");
993 }
994 }
995
996 void NapiHiSysEventUtil::ThrowParamMandatoryError(napi_env env, const std::string paramName)
997 {
998 ThrowError(env, NapiError::ERR_PARAM_CHECK, "Parameter error. The " + paramName + " parameter is mandatory.");
999 }
1000
1001 void NapiHiSysEventUtil::ThrowParamTypeError(napi_env env, const std::string paramName, std::string paramType)
1002 {
1003 ThrowError(env, NapiError::ERR_PARAM_CHECK, "Parameter error. The type of " + paramName + " must be "
1004 + paramType + ".");
1005 }
1006
1007 void NapiHiSysEventUtil::ThrowSystemAppPermissionError(napi_env env)
1008 {
1009 ThrowError(env, NapiError::ERR_NON_SYS_APP_PERMISSION, "Permission denied. "
1010 "System api can be invoked only by system applications.");
1011 }
1012
1013 napi_value NapiHiSysEventUtil::CreateError(napi_env env, int32_t code, const std::string& msg)
1014 {
1015 napi_value err = nullptr;
1016 napi_value napiCode = nullptr;
1017 NapiHiSysEventUtil::CreateStringValue(env, std::to_string(code), napiCode);
1018 napi_value napiStr = nullptr;
1019 NapiHiSysEventUtil::CreateStringValue(env, msg, napiStr);
1020 if (napi_create_error(env, napiCode, napiStr, &err) != napi_ok) {
1021 HILOG_ERROR(LOG_CORE, "failed to create napi error");
1022 }
1023 return err;
1024 }
1025
1026 void NapiHiSysEventUtil::ThrowError(napi_env env, const int32_t code, const std::string& msg)
1027 {
1028 if (napi_throw_error(env, std::to_string(code).c_str(), msg.c_str()) != napi_ok) {
1029 HILOG_ERROR(LOG_CORE, "failed to throw err, code=%{public}d, msg=%{public}s.", code, msg.c_str());
1030 }
1031 }
1032
1033 std::pair<int32_t, std::string> NapiHiSysEventUtil::GetErrorDetailByRet(napi_env env, const int32_t retCode)
1034 {
1035 HILOG_DEBUG(LOG_CORE, "original result code is %{public}d.", retCode);
1036 const std::unordered_map<int32_t, std::pair<int32_t, std::string>> errMap = {
1037 // common
1038 {ERR_NO_PERMISSION, {NapiError::ERR_PERMISSION_CHECK,
1039 "Permission denied. An attempt was made to read sysevent forbidden"
1040 " by permission: ohos.permission.READ_DFX_SYSEVENT."}},
1041 // write refer
1042 {ERR_DOMAIN_NAME_INVALID, {NapiError::ERR_INVALID_DOMAIN, INVALID_DOMAIN_DES}},
1043 {ERR_EVENT_NAME_INVALID, {NapiError::ERR_INVALID_EVENT_NAME, INVALID_NAME_DES}},
1044 {ERR_DOES_NOT_INIT, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1045 {ERR_OVER_SIZE, {NapiError::ERR_CONTENT_OVER_LIMIT, "The event length exceeds the limit"}},
1046 {ERR_KEY_NAME_INVALID, {NapiError::ERR_INVALID_PARAM_NAME, INVALID_PARAM_NAME_DES}},
1047 {ERR_VALUE_LENGTH_TOO_LONG, {NapiError::ERR_STR_LEN_OVER_LIMIT,
1048 "The size of the event parameter of the string type exceeds the limit"}},
1049 {ERR_KEY_NUMBER_TOO_MUCH, {NapiError::ERR_PARAM_COUNT_OVER_LIMIT,
1050 "The number of event parameters exceeds the limit"}},
1051 {ERR_ARRAY_TOO_MUCH, {NapiError::ERR_ARRAY_SIZE_OVER_LIMIT,
1052 "The number of event parameters of the array type exceeds the limit"}},
1053 // ipc common
1054 {ERR_SYS_EVENT_SERVICE_NOT_FOUND, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1055 {ERR_CAN_NOT_WRITE_DESCRIPTOR, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1056 {ERR_CAN_NOT_WRITE_PARCEL, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1057 {ERR_CAN_NOT_WRITE_REMOTE_OBJECT, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1058 {ERR_CAN_NOT_SEND_REQ, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1059 {ERR_CAN_NOT_READ_PARCEL, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1060 {ERR_SEND_FAIL, {NapiError::ERR_ENV_ABNORMAL, "Abnormal environment"}},
1061 // add watcher
1062 {ERR_TOO_MANY_WATCHERS, {NapiError::ERR_WATCHER_COUNT_OVER_LIMIT,
1063 "The number of watchers exceeds the limit"}},
1064 {ERR_TOO_MANY_WATCH_RULES, {NapiError::ERR_WATCH_RULE_COUNT_OVER_LIMIT,
1065 "The number of watch rules exceeds the limit"}},
1066 // remove watcher
1067 {ERR_LISTENER_NOT_EXIST, {NapiError::ERR_WATCHER_NOT_EXIST, "The watcher does not exist"}},
1068 {ERR_NAPI_LISTENER_NOT_FOUND, {NapiError::ERR_WATCHER_NOT_EXIST, "The watcher does not exist"}},
1069 // query refer
1070 {ERR_TOO_MANY_QUERY_RULES, {NapiError::ERR_QUERY_RULE_COUNT_OVER_LIMIT,
1071 "The number of query rules exceeds the limit"}},
1072 {ERR_TOO_MANY_CONCURRENT_QUERIES, {NapiError::ERR_CONCURRENT_QUERY_COUNT_OVER_LIMIT,
1073 "The number of concurrent queries exceeds the limit"}},
1074 {ERR_QUERY_TOO_FREQUENTLY, {NapiError::ERR_QUERY_TOO_FREQUENTLY, "The query frequency exceeds the limit"}},
1075 {NapiInnerError::ERR_INVALID_DOMAIN_IN_QUERY_RULE, {NapiError::ERR_INVALID_QUERY_RULE,
1076 INVALID_QUERY_RULE_DES}},
1077 {ERR_QUERY_RULE_INVALID, {NapiError::ERR_INVALID_QUERY_RULE, INVALID_QUERY_RULE_DES}},
1078 {NapiInnerError::ERR_INVALID_EVENT_NAME_IN_QUERY_RULE, {NapiError::ERR_INVALID_QUERY_RULE,
1079 INVALID_QUERY_RULE_DES}},
1080 // export
1081 {ERR_EXPORT_FREQUENCY_OVER_LIMIT, {NapiError::ERR_QUERY_TOO_FREQUENTLY,
1082 "The query frequency exceeds the limit"}},
1083 // add subscriber
1084 {ERR_TOO_MANY_EVENTS, {NapiError::ERR_QUERY_RULE_COUNT_OVER_LIMIT,
1085 "The number of query rules exceeds the limit"}},
1086 // remove subscriber
1087 {ERR_REMOVE_SUBSCRIBE, {NapiError::ERR_REMOVE_SUBSCRIBE, "Unsubscription failed"}},
1088 };
1089 return errMap.find(retCode) == errMap.end() ?
1090 std::make_pair(NapiError::ERR_ENV_ABNORMAL, "Abnormal environment") : errMap.at(retCode);
1091 }
1092
1093 napi_value NapiHiSysEventUtil::CreateErrorByRet(napi_env env, const int32_t retCode)
1094 {
1095 auto detail = GetErrorDetailByRet(env, retCode);
1096 return CreateError(env, detail.first, detail.second);
1097 }
1098
1099 void NapiHiSysEventUtil::ThrowErrorByRet(napi_env env, const int32_t retCode)
1100 {
1101 auto detail = GetErrorDetailByRet(env, retCode);
1102 ThrowError(env, detail.first, detail.second);
1103 }
1104
1105 bool NapiHiSysEventUtil::IsSystemAppCall()
1106 {
1107 uint64_t tokenId = IPCSkeleton::GetCallingFullTokenID();
1108 return Security::AccessToken::AccessTokenKit::IsSystemAppByFullTokenID(tokenId);
1109 }
1110
1111 bool NapiHiSysEventUtil::IsNullOrUndefined(napi_env env, const napi_value& val)
1112 {
1113 return IsValueTypeValid(env, val, napi_valuetype::napi_null) ||
1114 IsValueTypeValid(env, val, napi_valuetype::napi_undefined);
1115 }
1116 } // namespace HiviewDFX
1117 } // namespace OHOS