• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, &params);
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