1 /*
2  * Copyright (c) 2024 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 #include "napi_param_builder.h"
16 
17 #include "hiappevent_base.h"
18 #include "hiappevent_verify.h"
19 #include "hilog/log.h"
20 #include "napi_error.h"
21 #include "napi_util.h"
22 
23 #undef LOG_DOMAIN
24 #define LOG_DOMAIN 0xD002D07
25 
26 #undef LOG_TAG
27 #define LOG_TAG "NapiParamBuilder"
28 
29 namespace OHOS {
30 namespace HiviewDFX {
31 namespace {
32 constexpr size_t MIN_NUM_PARAMETERS = 2; // the min number of params for setEventParam
33 constexpr int INDEX_OF_PARAMS = 0;
34 constexpr int INDEX_OF_DOMAIN = 1;
35 constexpr int INDEX_OF_NAME = 2;
36 constexpr size_t MAX_LENGTH_OF_PARAM_NAME = 32;
37 const std::string PARAM_VALUE_TYPE = "boolean|number|string|array[string]";
38 }
39 using namespace OHOS::HiviewDFX::ErrorCode;
40 
IsValidParams(const napi_env env,const napi_value params[],size_t len)41 bool NapiParamBuilder::IsValidParams(const napi_env env, const napi_value params[], size_t len)
42 {
43     if (!NapiHiAppEventBuilder::IsValidEventParam(env, params[INDEX_OF_PARAMS])
44         || !NapiHiAppEventBuilder::IsValidEventDomain(env, params[INDEX_OF_DOMAIN])) {
45         return false;
46     }
47     return (len > MIN_NUM_PARAMETERS)
48         ? NapiHiAppEventBuilder::IsValidEventName(env, params[INDEX_OF_NAME])
49         : true;
50 }
51 
AddArrayParam2EventPack(napi_env env,const std::string & key,const napi_value arr)52 bool NapiParamBuilder::AddArrayParam2EventPack(napi_env env, const std::string &key,
53     const napi_value arr)
54 {
55     napi_valuetype type = NapiUtil::GetArrayType(env, arr);
56     if (type != napi_string) {
57         HILOG_ERROR(LOG_CORE, "array param value type is invalid");
58         result_ = ERROR_INVALID_LIST_PARAM_TYPE;
59         std::string errMsg = NapiUtil::CreateErrMsg("param value", PARAM_VALUE_TYPE);
60         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, errMsg, isV9_);
61         return false;
62     }
63     std::vector<std::string> strs;
64     NapiUtil::GetStrings(env, arr, strs);
65     appEventPack_->AddParam(key, strs);
66     return true;
67 }
68 
AddParams2EventPack(napi_env env,const napi_value paramObj)69 bool NapiParamBuilder::AddParams2EventPack(napi_env env, const napi_value paramObj)
70 {
71     std::vector<std::string> keys;
72     NapiUtil::GetPropertyNames(env, paramObj, keys);
73     for (auto key : keys) {
74         if (key.length() > MAX_LENGTH_OF_PARAM_NAME) {
75             result_ = ERROR_INVALID_PARAM_NAME;
76             HILOG_ERROR(LOG_CORE, "the length=%{public}zu of the param key is invalid", key.length());
77             break;
78         }
79         napi_value value = NapiUtil::GetProperty(env, paramObj, key);
80         if (value == nullptr) {
81             result_ = ERROR_INVALID_PARAM_VALUE_TYPE;
82             std::string errMsg = NapiUtil::CreateErrMsg("param value", PARAM_VALUE_TYPE);
83             NapiUtil::ThrowError(env, NapiError::ERR_PARAM, errMsg, isV9_);
84             return false;
85         }
86         if (!AddParam2EventPack(env, key, value)) {
87             return false;
88         }
89     }
90     return true;
91 }
92 
BuildCustomEventParamPack(napi_env env,const napi_value params[],size_t len)93 bool NapiParamBuilder::BuildCustomEventParamPack(napi_env env, const napi_value params[], size_t len)
94 {
95     std::string domain = NapiUtil::GetString(env, params[INDEX_OF_DOMAIN]);
96     std::string name;
97     if (len > MIN_NUM_PARAMETERS) {
98         name = NapiUtil::GetString(env, params[INDEX_OF_NAME]);
99     }
100     appEventPack_ = std::make_shared<AppEventPack>(domain, name);
101     return AddParams2EventPack(env, params[INDEX_OF_PARAMS]);
102 }
103 
BuildEventParam(const napi_env env,const napi_value params[],size_t len)104 std::shared_ptr<AppEventPack> NapiParamBuilder::BuildEventParam(const napi_env env,
105     const napi_value params[], size_t len)
106 {
107     if (len < MIN_NUM_PARAMETERS) {
108         NapiUtil::ThrowError(env, NapiError::ERR_PARAM, NapiUtil::CreateErrMsg("setEventParam"), isV9_);
109         return nullptr;
110     }
111     if (!IsValidParams(env, params, len)) {
112         return nullptr;
113     }
114     if (!BuildCustomEventParamPack(env, params, len)) {
115         return nullptr;
116     }
117 
118     // if the build is successful, the event verification is performed
119     if (appEventPack_ != nullptr && result_ >= 0) {
120         if (auto ret = VerifyCustomEventParams(appEventPack_); ret != 0) {
121             result_ = ret;
122         }
123     }
124     return appEventPack_;
125 }
126 } // namespace HiviewDFX
127 } // namespace OHOS
128