1 /*
2 * Copyright (c) 2022 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_common.h"
16 #include "accesstoken_log.h"
17
18 namespace OHOS {
19 namespace Security {
20 namespace AccessToken {
21 namespace {
22 static constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, SECURITY_DOMAIN_PRIVACY, "CommonNapi"};
23 } // namespace
24
IsCurrentThread(std::thread::id threadId)25 bool IsCurrentThread(std::thread::id threadId)
26 {
27 std::thread::id currentThread = std::this_thread::get_id();
28 if (threadId != currentThread) {
29 ACCESSTOKEN_LOG_ERROR(LABEL, "Napi_ref can not be compared,different threadId");
30 return false;
31 }
32 return true;
33 }
CompareCallbackRef(const napi_env env,napi_ref subscriberRef,napi_ref unsubscriberRef,std::thread::id threadId)34 bool CompareCallbackRef(const napi_env env, napi_ref subscriberRef, napi_ref unsubscriberRef, std::thread::id threadId)
35 {
36 if (!IsCurrentThread(threadId)) {
37 return false;
38 }
39 napi_value subscriberCallback;
40 NAPI_CALL_BASE(env,
41 napi_get_reference_value(env, subscriberRef, &subscriberCallback), false);
42 napi_value unsubscriberCallback;
43 NAPI_CALL_BASE(env,
44 napi_get_reference_value(env, unsubscriberRef, &unsubscriberCallback), false);
45 bool result = false;
46 NAPI_CALL_BASE(env,
47 napi_strict_equals(env, subscriberCallback, unsubscriberCallback, &result), false);
48 return result;
49 }
50
CheckType(const napi_env & env,const napi_value & value,const napi_valuetype & type)51 bool CheckType(const napi_env& env, const napi_value& value, const napi_valuetype& type)
52 {
53 napi_valuetype valuetype = napi_undefined;
54 napi_typeof(env, value, &valuetype);
55 if (valuetype != type) {
56 ACCESSTOKEN_LOG_ERROR(LABEL, "Value type dismatch, [%{public}d]->[%{public}d]", valuetype, type);
57 return false;
58 }
59 return true;
60 }
61
ParseBool(const napi_env & env,const napi_value & value,bool & result)62 bool ParseBool(const napi_env& env, const napi_value& value, bool& result)
63 {
64 if (!CheckType(env, value, napi_boolean)) {
65 return false;
66 }
67
68 if (napi_get_value_bool(env, value, &result) != napi_ok) {
69 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get value bool");
70 return false;
71 }
72 return true;
73 }
74
ParseInt32(const napi_env & env,const napi_value & value,int32_t & result)75 bool ParseInt32(const napi_env& env, const napi_value& value, int32_t& result)
76 {
77 if (!CheckType(env, value, napi_number)) {
78 return false;
79 }
80 if (napi_get_value_int32(env, value, &result) != napi_ok) {
81 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get value int32");
82 return false;
83 }
84 return true;
85 }
86
ParseInt64(const napi_env & env,const napi_value & value,int64_t & result)87 bool ParseInt64(const napi_env& env, const napi_value& value, int64_t& result)
88 {
89 if (!CheckType(env, value, napi_number)) {
90 return false;
91 }
92 if (napi_get_value_int64(env, value, &result) != napi_ok) {
93 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get value int64");
94 return false;
95 }
96 return true;
97 }
98
ParseUint32(const napi_env & env,const napi_value & value,uint32_t & result)99 bool ParseUint32(const napi_env& env, const napi_value& value, uint32_t& result)
100 {
101 if (!CheckType(env, value, napi_number)) {
102 return false;
103 }
104 if (napi_get_value_uint32(env, value, &result) != napi_ok) {
105 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get value uint32");
106 return false;
107 }
108 return true;
109 }
110
ParseString(const napi_env & env,const napi_value & value,std::string & result)111 bool ParseString(const napi_env& env, const napi_value& value, std::string& result)
112 {
113 if (!CheckType(env, value, napi_string)) {
114 return false;
115 }
116 size_t size;
117 if (napi_get_value_string_utf8(env, value, nullptr, 0, &size) != napi_ok) {
118 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get string size");
119 return false;
120 }
121 result.reserve(size + 1);
122 result.resize(size);
123 if (napi_get_value_string_utf8(env, value, result.data(), size + 1, &size) != napi_ok) {
124 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get value string");
125 return false;
126 }
127 return true;
128 }
129
ParseStringArray(const napi_env & env,const napi_value & value,std::vector<std::string> & result)130 bool ParseStringArray(const napi_env& env, const napi_value& value, std::vector<std::string>& result)
131 {
132 if (!IsArray(env, value)) {
133 return false;
134 }
135
136 uint32_t length = 0;
137 napi_get_array_length(env, value, &length);
138
139 ACCESSTOKEN_LOG_INFO(LABEL, "Array size is %{public}d", length);
140
141 if (length == 0) {
142 ACCESSTOKEN_LOG_INFO(LABEL, "Array is empty");
143 return true;
144 }
145
146 napi_value valueArray;
147 for (uint32_t i = 0; i < length; i++) {
148 napi_get_element(env, value, i, &valueArray);
149
150 std::string str;
151 if (!ParseString(env, valueArray, str)) {
152 return false;
153 }
154 result.emplace_back(str);
155 }
156 return true;
157 }
158
ParseAccessTokenIDArray(const napi_env & env,const napi_value & value,std::vector<AccessTokenID> & result)159 bool ParseAccessTokenIDArray(const napi_env& env, const napi_value& value, std::vector<AccessTokenID>& result)
160 {
161 uint32_t length = 0;
162 if (!IsArray(env, value)) {
163 return false;
164 }
165 napi_get_array_length(env, value, &length);
166 napi_value valueArray;
167 for (uint32_t i = 0; i < length; i++) {
168 napi_get_element(env, value, i, &valueArray);
169 uint32_t res;
170 if (!ParseUint32(env, valueArray, res)) {
171 return false;
172 }
173 result.emplace_back(res);
174 }
175 return true;
176 };
177
IsArray(const napi_env & env,const napi_value & value)178 bool IsArray(const napi_env& env, const napi_value& value)
179 {
180 bool isArray = false;
181 napi_status ret = napi_is_array(env, value, &isArray);
182 if (ret != napi_ok) {
183 return false;
184 }
185 return isArray;
186 }
187
IsUndefinedOrNull(const napi_env & env,const napi_value & value)188 bool IsUndefinedOrNull(const napi_env& env, const napi_value& value)
189 {
190 napi_valuetype valueType = napi_undefined;
191 napi_typeof(env, value, &valueType);
192 return (valueType == napi_undefined) || (valueType == napi_null) ;
193 }
194
IsNeedParseProperty(const napi_env & env,const napi_value & value,const std::string & key,napi_value & property)195 bool IsNeedParseProperty(
196 const napi_env& env, const napi_value& value, const std::string& key, napi_value& property)
197 {
198 bool hasProp = false;
199 property = nullptr;
200 napi_has_named_property(env, value, key.c_str(), &hasProp);
201 if (hasProp) {
202 napi_get_named_property(env, value, key.c_str(), &property);
203 napi_valuetype valueType = napi_undefined;
204 napi_typeof(env, property, &valueType);
205 return (valueType != napi_undefined) && (valueType != napi_null);
206 }
207 return false;
208 }
209
ParseCallback(const napi_env & env,const napi_value & value,napi_ref & result)210 bool ParseCallback(const napi_env& env, const napi_value& value, napi_ref& result)
211 {
212 if (!CheckType(env, value, napi_function)) {
213 return false;
214 }
215 if (napi_create_reference(env, value, 1, &result) != napi_ok) {
216 ACCESSTOKEN_LOG_ERROR(LABEL, "Cannot get value callback");
217 return false;
218 }
219 return true;
220 }
221 } // namespace AccessToken
222 } // namespace Security
223 } // namespace OHOS
224