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