• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
28 const std::map<int32_t, std::string> ERROR_CODE_CONVERT_MESSAGE_MAP = {
29     {E_PRINT_NO_PERMISSION, "the application does not have permission to call this function."},
30     {E_PRINT_ILLEGAL_USE_OF_SYSTEM_API, "not system application."},
31     {E_PRINT_INVALID_PARAMETER,
32         "Parameter error. Possible causes: 1.Mandatory parameters are left unspecified; 2.Incorrect parameter types."},
33     {E_PRINT_GENERIC_FAILURE, "Generic failure of print."},
34     {E_PRINT_RPC_FAILURE, "RPC failure."},
35     {E_PRINT_SERVER_FAILURE, "Failure of print service."},
36     {E_PRINT_INVALID_EXTENSION, "Invalid print extension."},
37     {E_PRINT_INVALID_PRINTER, "Invalid printer."},
38     {E_PRINT_INVALID_PRINTJOB, "Invalid print job."},
39     {E_PRINT_FILE_IO, "File i/o error."},
40     {E_PRINT_INVALID_TOKEN, "Invalid token."},
41     {E_PRINT_INVALID_USERID, "Invalid user id."},
42     {E_PRINT_TOO_MANY_FILES, "Number of files exceeding the upper limit."},
43 };
44 static const std::string ERROR_MESSAGE_OUT_OF_DEFINITION = "error is out of definition.";
45 
GetValueType(napi_env env,napi_value value)46 napi_valuetype NapiPrintUtils::GetValueType(napi_env env, napi_value value)
47 {
48     if (value == nullptr) {
49         return napi_undefined;
50     }
51 
52     napi_valuetype valueType = napi_undefined;
53     PRINT_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
54     return valueType;
55 }
56 
57 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)58 bool NapiPrintUtils::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
59 {
60     if (object == nullptr) {
61         return false;
62     }
63     bool hasProperty = false;
64     PRINT_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
65     return hasProperty;
66 }
67 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)68 napi_value NapiPrintUtils::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
69 {
70     if (object == nullptr) {
71         return nullptr;
72     }
73     napi_value value = nullptr;
74     bool hasProperty = false;
75     PRINT_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty));
76     if (!hasProperty) {
77         return value;
78     }
79     PRINT_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
80     return value;
81 }
82 
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)83 void NapiPrintUtils::SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
84 {
85     if (object == nullptr) {
86         return;
87     }
88     (void)napi_set_named_property(env, object, name.c_str(), value);
89 }
90 
GetPropertyNames(napi_env env,napi_value object)91 std::vector<std::string> NapiPrintUtils::GetPropertyNames(napi_env env, napi_value object)
92 {
93     std::vector<std::string> ret;
94     if (object == nullptr) {
95         return ret;
96     }
97     napi_value names = nullptr;
98     PRINT_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
99     uint32_t length = 0;
100     PRINT_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
101     for (uint32_t index = 0; index < length; ++index) {
102         napi_value name = nullptr;
103         if (napi_get_element(env, names, index, &name) != napi_ok) {
104             continue;
105         }
106         if (GetValueType(env, name) != napi_string) {
107             continue;
108         }
109         ret.emplace_back(GetStringFromValueUtf8(env, name));
110     }
111     return ret;
112 }
113 
114 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)115 napi_value NapiPrintUtils::CreateUint32(napi_env env, uint32_t code)
116 {
117     napi_value value = nullptr;
118     if (napi_create_uint32(env, code, &value) != napi_ok) {
119         return nullptr;
120     }
121     return value;
122 }
123 
GetUint32FromValue(napi_env env,napi_value value)124 uint32_t NapiPrintUtils::GetUint32FromValue(napi_env env, napi_value value)
125 {
126     if (value == nullptr) {
127         return 0;
128     }
129     uint32_t ret = 0;
130     PRINT_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
131     return ret;
132 }
133 
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)134 uint32_t NapiPrintUtils::GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
135 {
136     if (object == nullptr) {
137         return 0;
138     }
139     if (!HasNamedProperty(env, object, propertyName)) {
140         return 0;
141     }
142     napi_value value = GetNamedProperty(env, object, propertyName);
143     return GetUint32FromValue(env, value);
144 }
145 
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)146 void NapiPrintUtils::SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
147 {
148     if (object == nullptr) {
149         return;
150     }
151     napi_value jsValue = CreateUint32(env, value);
152     if (GetValueType(env, jsValue) != napi_number) {
153         return;
154     }
155 
156     napi_set_named_property(env, object, name.c_str(), jsValue);
157 }
158 
159 /* INT32 */
CreateInt32(napi_env env,int32_t code)160 napi_value NapiPrintUtils::CreateInt32(napi_env env, int32_t code)
161 {
162     napi_value value = nullptr;
163     if (napi_create_int32(env, code, &value) != napi_ok) {
164         return nullptr;
165     }
166     return value;
167 }
168 
GetInt32FromValue(napi_env env,napi_value value)169 int32_t NapiPrintUtils::GetInt32FromValue(napi_env env, napi_value value)
170 {
171     if (value == nullptr) {
172         return 0;
173     }
174     int32_t ret = 0;
175     PRINT_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
176     return ret;
177 }
178 
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)179 int32_t NapiPrintUtils::GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
180 {
181     if (object == nullptr) {
182         return 0;
183     }
184     if (!HasNamedProperty(env, object, propertyName)) {
185         return 0;
186     }
187     napi_value value = GetNamedProperty(env, object, propertyName);
188     return GetInt32FromValue(env, value);
189 }
190 
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)191 void NapiPrintUtils::SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
192 {
193     if (object == nullptr) {
194         return;
195     }
196     napi_value jsValue = CreateInt32(env, value);
197     if (GetValueType(env, jsValue) != napi_number) {
198         return;
199     }
200 
201     napi_set_named_property(env, object, name.c_str(), jsValue);
202 }
203 
204 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)205 napi_value NapiPrintUtils::CreateStringUtf8(napi_env env, const std::string &str)
206 {
207     napi_value value = nullptr;
208     if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
209         return nullptr;
210     }
211     return value;
212 }
213 
GetStringFromValueUtf8(napi_env env,napi_value value)214 std::string NapiPrintUtils::GetStringFromValueUtf8(napi_env env, napi_value value)
215 {
216     if (value == nullptr) {
217         return "";
218     }
219     std::string result;
220     std::vector<char> str(MAX_STRING_LENGTH + 1, '\0');
221     size_t length = 0;
222     PRINT_CALL_BASE(env, napi_get_value_string_utf8(env, value, &str[0], MAX_STRING_LENGTH, &length), result);
223     if (length > 0) {
224         return result.append(&str[0], length);
225     }
226     return result;
227 }
228 
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)229 std::string NapiPrintUtils::GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
230 {
231     if (object == nullptr) {
232         return "";
233     }
234     if (!HasNamedProperty(env, object, propertyName)) {
235         return "";
236     }
237     napi_value value = GetNamedProperty(env, object, propertyName);
238     return GetStringFromValueUtf8(env, value);
239 }
240 
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)241 void NapiPrintUtils::SetStringPropertyUtf8(
242     napi_env env, napi_value object, const std::string &name, const std::string &value)
243 {
244     if (object == nullptr) {
245         return;
246     }
247     napi_value jsValue = CreateStringUtf8(env, value);
248     if (GetValueType(env, jsValue) != napi_string) {
249         return;
250     }
251     napi_set_named_property(env, object, name.c_str(), jsValue);
252 }
253 
254 /* array buffer */
255 
CreateArrayBuffer(napi_env env,size_t length,void ** data)256 napi_value NapiPrintUtils::CreateArrayBuffer(napi_env env, size_t length, void **data)
257 {
258     napi_value object = nullptr;
259     PRINT_CALL(env, napi_create_arraybuffer(env, length, data, &object));
260     return object;
261 }
262 
ValueIsArrayBuffer(napi_env env,napi_value value)263 bool NapiPrintUtils::ValueIsArrayBuffer(napi_env env, napi_value value)
264 {
265     if (value == nullptr) {
266         return false;
267     }
268     bool isArrayBuffer = false;
269     PRINT_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
270     return isArrayBuffer;
271 }
272 
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)273 void *NapiPrintUtils::GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
274 {
275     if (value == nullptr || length == nullptr) {
276         return nullptr;
277     }
278 
279     void *data = nullptr;
280     PRINT_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
281     return data;
282 }
283 
284 /* object */
CreateObject(napi_env env)285 napi_value NapiPrintUtils::CreateObject(napi_env env)
286 {
287     napi_value object = nullptr;
288     PRINT_CALL(env, napi_create_object(env, &object));
289     return object;
290 }
291 
292 /* undefined */
GetUndefined(napi_env env)293 napi_value NapiPrintUtils::GetUndefined(napi_env env)
294 {
295     napi_value undefined = nullptr;
296     PRINT_CALL(env, napi_get_undefined(env, &undefined));
297     return undefined;
298 }
299 
300 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)301 napi_value NapiPrintUtils::CallFunction(
302     napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
303 {
304     if (func == nullptr) {
305         return nullptr;
306     }
307     napi_value res = nullptr;
308     PRINT_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
309     return res;
310 }
311 
CreateFunction(napi_env env,const std::string & name,napi_callback func,void * arg)312 napi_value NapiPrintUtils::CreateFunction
313     (napi_env env, const std::string &name, napi_callback func, void *arg)
314 {
315     napi_value res = nullptr;
316     PRINT_CALL(env, napi_create_function(env, name.c_str(), NAPI_AUTO_LENGTH, func, arg, &res));
317     return res;
318 }
319 
320 /* reference */
CreateReference(napi_env env,napi_value callback)321 napi_ref NapiPrintUtils::CreateReference(napi_env env, napi_value callback)
322 {
323     if (callback == nullptr) {
324         return nullptr;
325     }
326     napi_ref callbackRef = nullptr;
327     PRINT_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
328     return callbackRef;
329 }
330 
GetReference(napi_env env,napi_ref callbackRef)331 napi_value NapiPrintUtils::GetReference(napi_env env, napi_ref callbackRef)
332 {
333     if (callbackRef == nullptr) {
334         return nullptr;
335     }
336     napi_value callback = nullptr;
337     PRINT_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
338     return callback;
339 }
340 
DeleteReference(napi_env env,napi_ref callbackRef)341 void NapiPrintUtils::DeleteReference(napi_env env, napi_ref callbackRef)
342 {
343     (void)napi_delete_reference(env, callbackRef);
344 }
345 
346 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)347 bool NapiPrintUtils::GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
348 {
349     if (object == nullptr) {
350         return false;
351     }
352     if (!HasNamedProperty(env, object, propertyName)) {
353         return false;
354     }
355     napi_value value = GetNamedProperty(env, object, propertyName);
356     bool ret = false;
357     PRINT_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
358     return ret;
359 }
360 
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)361 void NapiPrintUtils::SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
362 {
363     if (object == nullptr) {
364         return;
365     }
366     napi_value jsValue = nullptr;
367     PRINT_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
368     if (GetValueType(env, jsValue) != napi_boolean) {
369         return;
370     }
371 
372     napi_set_named_property(env, object, name.c_str(), jsValue);
373 }
374 
375 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)376 void NapiPrintUtils::DefineProperties(
377     napi_env env, napi_value object, const std::initializer_list<napi_property_descriptor> &properties)
378 {
379     std::vector<napi_property_descriptor> descriptors(properties.begin(), properties.end());
380 
381     (void)napi_define_properties(env, object, properties.size(), descriptors.data());
382 }
383 
GetValueString(napi_env env,napi_value value)384 std::string NapiPrintUtils::GetValueString(napi_env env, napi_value value)
385 {
386     if (value == nullptr) {
387         return "";
388     }
389     std::string resultValue = "";
390     char value_string[256] = { 0 };
391     size_t value_size = 256;
392     size_t result = 0;
393     napi_status status = napi_get_value_string_utf8(env, value, value_string, value_size, &result);
394     if (status == napi_ok && result > 0) {
395         resultValue = value_string;
396     }
397     return resultValue;
398 }
399 
GetJsVal(napi_env env,napi_callback_info info,napi_value argv[],size_t length)400 size_t NapiPrintUtils::GetJsVal(napi_env env, napi_callback_info info, napi_value argv[], size_t length)
401 {
402     size_t argc = length;
403     napi_value thisVal = nullptr;
404     void *data = nullptr;
405     napi_get_cb_info(env, info, &argc, argv, &thisVal, &data);
406     return argc;
407 }
408 
VerifyProperty(std::vector<std::string> & names,std::map<std::string,PrintParamStatus> & propertyList)409 bool NapiPrintUtils::VerifyProperty(
410     std::vector<std::string> &names, std::map<std::string, PrintParamStatus> &propertyList)
411 {
412     for (const auto& name : names) {
413         if (propertyList.find(name) == propertyList.end()) {
414             PRINT_HILOGE("Invalid property: %{public}s", name.c_str());
415             return false;
416         }
417         propertyList[name] = PRINT_PARAM_SET;
418     }
419 
420     for (const auto& propertyItem : propertyList) {
421         if (propertyItem.second == PRINT_PARAM_NOT_SET) {
422             PRINT_HILOGE("Missing Property: %{public}s", propertyItem.first.c_str());
423             return false;
424         }
425     }
426     return true;
427 }
428 
GetPrintErrorMsg(int32_t errorCode)429 std::string NapiPrintUtils::GetPrintErrorMsg(int32_t errorCode)
430 {
431     auto msg = PRINT_ERROR_MSG_MAP.find(static_cast<PrintErrorCode>(errorCode));
432     if (msg != PRINT_ERROR_MSG_MAP.end()) {
433         return msg->second;
434     }
435     return "";
436 }
437 
CheckCallerIsSystemApp()438 bool NapiPrintUtils::CheckCallerIsSystemApp()
439 {
440     auto callerToken = IPCSkeleton::GetCallingTokenID();
441     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
442     if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
443         tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
444         PRINT_HILOGD("tokenType check passed.");
445         return true;
446     }
447     auto accessTokenId = IPCSkeleton::GetCallingFullTokenID();
448     return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenId);
449 }
450 
GetErrorMsgByErrorCode(int32_t code)451 const std::string NapiPrintUtils::GetErrorMsgByErrorCode(int32_t code)
452 {
453     PRINT_HILOGD("GetErrorMsgByErrorCode start");
454     auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code);
455     if (iter == ERROR_CODE_CONVERT_MESSAGE_MAP.end()) {
456         PRINT_HILOGE("error is out of definition.");
457         return ERROR_MESSAGE_OUT_OF_DEFINITION;
458     }
459     PRINT_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str());
460     return iter->second;
461 }
462 
CreateJsError(napi_env env,int32_t errCode)463 napi_value NapiPrintUtils::CreateJsError(napi_env env, int32_t errCode)
464 {
465     std::string errMsg = GetErrorMsgByErrorCode(errCode);
466     PRINT_HILOGD("CreateJsError errCode: %{public}d, errMsg: %{public}s", errCode, errMsg.c_str());
467 
468     napi_value code = nullptr;
469     napi_status status = napi_create_int32(env, errCode, &code);
470     if (status != napi_ok) {
471         PRINT_HILOGE("napi create error code failed");
472         return nullptr;
473     }
474 
475     napi_value message = nullptr;
476     status = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
477     if (status != napi_ok) {
478         PRINT_HILOGE("napi create error message failed");
479         return nullptr;
480     }
481 
482     napi_value errorObj = nullptr;
483     status = napi_create_error(env, code, message, &errorObj);
484     if (status != napi_ok) {
485         PRINT_HILOGE("napi create js error failed");
486         return nullptr;
487     }
488 
489     return errorObj;
490 }
491 }  // namespace OHOS::Print
492