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
16 #include "napi_print_utils.h"
17
18 #include "ability.h"
19 #include "accesstoken_kit.h"
20 #include "napi_base_context.h"
21 #include "print_constant.h"
22 #include "print_log.h"
23 #include "securec.h"
24 #include "tokenid_kit.h"
25
26 namespace OHOS::Print {
27 static constexpr const int MAX_STRING_LENGTH = 65536;
GetValueType(napi_env env,napi_value value)28 napi_valuetype NapiPrintUtils::GetValueType(napi_env env, napi_value value)
29 {
30 if (value == nullptr) {
31 return napi_undefined;
32 }
33
34 napi_valuetype valueType = napi_undefined;
35 PRINT_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
36 return valueType;
37 }
38
39 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)40 bool NapiPrintUtils::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
41 {
42 bool hasProperty = false;
43 PRINT_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
44 return hasProperty;
45 }
46
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)47 napi_value NapiPrintUtils::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
48 {
49 napi_value value = nullptr;
50 bool hasProperty = false;
51 PRINT_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty));
52 if (!hasProperty) {
53 return value;
54 }
55 PRINT_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
56 return value;
57 }
58
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)59 void NapiPrintUtils::SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
60 {
61 (void)napi_set_named_property(env, object, name.c_str(), value);
62 }
63
GetPropertyNames(napi_env env,napi_value object)64 std::vector<std::string> NapiPrintUtils::GetPropertyNames(napi_env env, napi_value object)
65 {
66 std::vector<std::string> ret;
67 napi_value names = nullptr;
68 PRINT_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
69 uint32_t length = 0;
70 PRINT_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
71 for (uint32_t index = 0; index < length; ++index) {
72 napi_value name = nullptr;
73 if (napi_get_element(env, names, index, &name) != napi_ok) {
74 continue;
75 }
76 if (GetValueType(env, name) != napi_string) {
77 continue;
78 }
79 ret.emplace_back(GetStringFromValueUtf8(env, name));
80 }
81 return ret;
82 }
83
84 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)85 napi_value NapiPrintUtils::CreateUint32(napi_env env, uint32_t code)
86 {
87 napi_value value = nullptr;
88 if (napi_create_uint32(env, code, &value) != napi_ok) {
89 return nullptr;
90 }
91 return value;
92 }
93
GetUint32FromValue(napi_env env,napi_value value)94 uint32_t NapiPrintUtils::GetUint32FromValue(napi_env env, napi_value value)
95 {
96 uint32_t ret = 0;
97 PRINT_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
98 return ret;
99 }
100
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)101 uint32_t NapiPrintUtils::GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
102 {
103 if (!HasNamedProperty(env, object, propertyName)) {
104 return 0;
105 }
106 napi_value value = GetNamedProperty(env, object, propertyName);
107 return GetUint32FromValue(env, value);
108 }
109
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)110 void NapiPrintUtils::SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
111 {
112 napi_value jsValue = CreateUint32(env, value);
113 if (GetValueType(env, jsValue) != napi_number) {
114 return;
115 }
116
117 napi_set_named_property(env, object, name.c_str(), jsValue);
118 }
119
120 /* INT32 */
CreateInt32(napi_env env,int32_t code)121 napi_value NapiPrintUtils::CreateInt32(napi_env env, int32_t code)
122 {
123 napi_value value = nullptr;
124 if (napi_create_int32(env, code, &value) != napi_ok) {
125 return nullptr;
126 }
127 return value;
128 }
129
GetInt32FromValue(napi_env env,napi_value value)130 int32_t NapiPrintUtils::GetInt32FromValue(napi_env env, napi_value value)
131 {
132 int32_t ret = 0;
133 PRINT_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
134 return ret;
135 }
136
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)137 int32_t NapiPrintUtils::GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
138 {
139 if (!HasNamedProperty(env, object, propertyName)) {
140 return 0;
141 }
142 napi_value value = GetNamedProperty(env, object, propertyName);
143 return GetInt32FromValue(env, value);
144 }
145
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)146 void NapiPrintUtils::SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
147 {
148 napi_value jsValue = CreateInt32(env, value);
149 if (GetValueType(env, jsValue) != napi_number) {
150 return;
151 }
152
153 napi_set_named_property(env, object, name.c_str(), jsValue);
154 }
155
156 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)157 napi_value NapiPrintUtils::CreateStringUtf8(napi_env env, const std::string &str)
158 {
159 napi_value value = nullptr;
160 if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
161 return nullptr;
162 }
163 return value;
164 }
165
GetStringFromValueUtf8(napi_env env,napi_value value)166 std::string NapiPrintUtils::GetStringFromValueUtf8(napi_env env, napi_value value)
167 {
168 std::string result;
169 std::vector<char> str(MAX_STRING_LENGTH + 1, '\0');
170 size_t length = 0;
171 PRINT_CALL_BASE(env, napi_get_value_string_utf8(env, value, &str[0], MAX_STRING_LENGTH, &length), result);
172 if (length > 0) {
173 return result.append(&str[0], length);
174 }
175 return result;
176 }
177
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)178 std::string NapiPrintUtils::GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
179 {
180 if (!HasNamedProperty(env, object, propertyName)) {
181 return "";
182 }
183 napi_value value = GetNamedProperty(env, object, propertyName);
184 return GetStringFromValueUtf8(env, value);
185 }
186
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)187 void NapiPrintUtils::SetStringPropertyUtf8(
188 napi_env env, napi_value object, const std::string &name, const std::string &value)
189 {
190 napi_value jsValue = CreateStringUtf8(env, value);
191 if (GetValueType(env, jsValue) != napi_string) {
192 return;
193 }
194 napi_set_named_property(env, object, name.c_str(), jsValue);
195 }
196
197 /* array buffer */
198
CreateArrayBuffer(napi_env env,size_t length,void ** data)199 napi_value NapiPrintUtils::CreateArrayBuffer(napi_env env, size_t length, void **data)
200 {
201 napi_value object = nullptr;
202 PRINT_CALL(env, napi_create_arraybuffer(env, length, data, &object));
203 return object;
204 }
205
ValueIsArrayBuffer(napi_env env,napi_value value)206 bool NapiPrintUtils::ValueIsArrayBuffer(napi_env env, napi_value value)
207 {
208 bool isArrayBuffer = false;
209 PRINT_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
210 return isArrayBuffer;
211 }
212
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)213 void *NapiPrintUtils::GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
214 {
215 if (length == nullptr) {
216 return nullptr;
217 }
218
219 void *data = nullptr;
220 PRINT_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
221 return data;
222 }
223
224 /* object */
CreateObject(napi_env env)225 napi_value NapiPrintUtils::CreateObject(napi_env env)
226 {
227 napi_value object = nullptr;
228 PRINT_CALL(env, napi_create_object(env, &object));
229 return object;
230 }
231
232 /* undefined */
GetUndefined(napi_env env)233 napi_value NapiPrintUtils::GetUndefined(napi_env env)
234 {
235 napi_value undefined = nullptr;
236 PRINT_CALL(env, napi_get_undefined(env, &undefined));
237 return undefined;
238 }
239
240 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)241 napi_value NapiPrintUtils::CallFunction(
242 napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
243 {
244 napi_value res = nullptr;
245 PRINT_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
246 return res;
247 }
248
CreateFunction(napi_env env,const std::string & name,napi_callback func,void * arg)249 napi_value NapiPrintUtils::CreateFunction
250 (napi_env env, const std::string &name, napi_callback func, void *arg)
251 {
252 napi_value res = nullptr;
253 PRINT_CALL(env, napi_create_function(env, name.c_str(), NAPI_AUTO_LENGTH, func, arg, &res));
254 return res;
255 }
256
257 /* reference */
CreateReference(napi_env env,napi_value callback)258 napi_ref NapiPrintUtils::CreateReference(napi_env env, napi_value callback)
259 {
260 napi_ref callbackRef = nullptr;
261 PRINT_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
262 return callbackRef;
263 }
264
GetReference(napi_env env,napi_ref callbackRef)265 napi_value NapiPrintUtils::GetReference(napi_env env, napi_ref callbackRef)
266 {
267 napi_value callback = nullptr;
268 PRINT_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
269 return callback;
270 }
271
DeleteReference(napi_env env,napi_ref callbackRef)272 void NapiPrintUtils::DeleteReference(napi_env env, napi_ref callbackRef)
273 {
274 (void)napi_delete_reference(env, callbackRef);
275 }
276
277 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)278 bool NapiPrintUtils::GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
279 {
280 if (!HasNamedProperty(env, object, propertyName)) {
281 return false;
282 }
283 napi_value value = GetNamedProperty(env, object, propertyName);
284 bool ret = false;
285 PRINT_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
286 return ret;
287 }
288
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)289 void NapiPrintUtils::SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
290 {
291 napi_value jsValue = nullptr;
292 PRINT_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
293 if (GetValueType(env, jsValue) != napi_boolean) {
294 return;
295 }
296
297 napi_set_named_property(env, object, name.c_str(), jsValue);
298 }
299
300 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)301 void NapiPrintUtils::DefineProperties(
302 napi_env env, napi_value object, const std::initializer_list<napi_property_descriptor> &properties)
303 {
304 std::vector<napi_property_descriptor> descriptors(properties.begin(), properties.end());
305
306 (void)napi_define_properties(env, object, properties.size(), descriptors.data());
307 }
308
GetValueString(napi_env env,napi_value value)309 std::string NapiPrintUtils::GetValueString(napi_env env, napi_value value)
310 {
311 std::string resultValue = "";
312 char value_string[256] = { 0 };
313 size_t value_size = 256;
314 size_t result = 0;
315 napi_status status = napi_get_value_string_utf8(env, value, value_string, value_size, &result);
316 if (status == napi_ok && result > 0) {
317 resultValue = value_string;
318 }
319 return resultValue;
320 }
321
GetJsVal(napi_env env,napi_callback_info info,napi_value argv[],size_t length)322 size_t NapiPrintUtils::GetJsVal(napi_env env, napi_callback_info info, napi_value argv[], size_t length)
323 {
324 size_t argc = length;
325 napi_value thisVal = nullptr;
326 void *data = nullptr;
327 napi_get_cb_info(env, info, &argc, argv, &thisVal, &data);
328 return argc;
329 }
330
VerifyProperty(std::vector<std::string> & names,std::map<std::string,PrintParamStatus> & propertyList)331 bool NapiPrintUtils::VerifyProperty(
332 std::vector<std::string> &names, std::map<std::string, PrintParamStatus> &propertyList)
333 {
334 for (const auto& name : names) {
335 if (propertyList.find(name) == propertyList.end()) {
336 PRINT_HILOGE("Invalid property: %{public}s", name.c_str());
337 return false;
338 }
339 propertyList[name] = PRINT_PARAM_SET;
340 }
341
342 for (const auto& propertyItem : propertyList) {
343 if (propertyItem.second == PRINT_PARAM_NOT_SET) {
344 PRINT_HILOGE("Missing Property: %{public}s", propertyItem.first.c_str());
345 return false;
346 }
347 }
348 return true;
349 }
350
GetPrintErrorMsg(int32_t errorCode)351 std::string NapiPrintUtils::GetPrintErrorMsg(int32_t errorCode)
352 {
353 auto msg = PRINT_ERROR_MSG_MAP.find(static_cast<PrintErrorCode>(errorCode));
354 if (msg != PRINT_ERROR_MSG_MAP.end()) {
355 return msg->second;
356 }
357 return "";
358 }
359
CheckCallerIsSystemApp()360 bool NapiPrintUtils::CheckCallerIsSystemApp()
361 {
362 auto callerToken = IPCSkeleton::GetCallingTokenID();
363 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
364 if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
365 tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
366 PRINT_HILOGD("tokenType check passed.");
367 return true;
368 }
369 auto accessTokenId = IPCSkeleton::GetCallingFullTokenID();
370 return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenId);
371 }
372 } // namespace OHOS::Print
373