• 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     bool hasProperty = false;
61     PRINT_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
62     return hasProperty;
63 }
64 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)65 napi_value NapiPrintUtils::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
66 {
67     napi_value value = nullptr;
68     bool hasProperty = false;
69     PRINT_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty));
70     if (!hasProperty) {
71         return value;
72     }
73     PRINT_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
74     return value;
75 }
76 
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)77 void NapiPrintUtils::SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
78 {
79     (void)napi_set_named_property(env, object, name.c_str(), value);
80 }
81 
GetPropertyNames(napi_env env,napi_value object)82 std::vector<std::string> NapiPrintUtils::GetPropertyNames(napi_env env, napi_value object)
83 {
84     std::vector<std::string> ret;
85     napi_value names = nullptr;
86     PRINT_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
87     uint32_t length = 0;
88     PRINT_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
89     for (uint32_t index = 0; index < length; ++index) {
90         napi_value name = nullptr;
91         if (napi_get_element(env, names, index, &name) != napi_ok) {
92             continue;
93         }
94         if (GetValueType(env, name) != napi_string) {
95             continue;
96         }
97         ret.emplace_back(GetStringFromValueUtf8(env, name));
98     }
99     return ret;
100 }
101 
102 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)103 napi_value NapiPrintUtils::CreateUint32(napi_env env, uint32_t code)
104 {
105     napi_value value = nullptr;
106     if (napi_create_uint32(env, code, &value) != napi_ok) {
107         return nullptr;
108     }
109     return value;
110 }
111 
GetUint32FromValue(napi_env env,napi_value value)112 uint32_t NapiPrintUtils::GetUint32FromValue(napi_env env, napi_value value)
113 {
114     uint32_t ret = 0;
115     PRINT_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
116     return ret;
117 }
118 
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)119 uint32_t NapiPrintUtils::GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
120 {
121     if (!HasNamedProperty(env, object, propertyName)) {
122         return 0;
123     }
124     napi_value value = GetNamedProperty(env, object, propertyName);
125     return GetUint32FromValue(env, value);
126 }
127 
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)128 void NapiPrintUtils::SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
129 {
130     napi_value jsValue = CreateUint32(env, value);
131     if (GetValueType(env, jsValue) != napi_number) {
132         return;
133     }
134 
135     napi_set_named_property(env, object, name.c_str(), jsValue);
136 }
137 
138 /* INT32 */
CreateInt32(napi_env env,int32_t code)139 napi_value NapiPrintUtils::CreateInt32(napi_env env, int32_t code)
140 {
141     napi_value value = nullptr;
142     if (napi_create_int32(env, code, &value) != napi_ok) {
143         return nullptr;
144     }
145     return value;
146 }
147 
GetInt32FromValue(napi_env env,napi_value value)148 int32_t NapiPrintUtils::GetInt32FromValue(napi_env env, napi_value value)
149 {
150     int32_t ret = 0;
151     PRINT_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
152     return ret;
153 }
154 
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)155 int32_t NapiPrintUtils::GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
156 {
157     if (!HasNamedProperty(env, object, propertyName)) {
158         return 0;
159     }
160     napi_value value = GetNamedProperty(env, object, propertyName);
161     return GetInt32FromValue(env, value);
162 }
163 
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)164 void NapiPrintUtils::SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
165 {
166     napi_value jsValue = CreateInt32(env, value);
167     if (GetValueType(env, jsValue) != napi_number) {
168         return;
169     }
170 
171     napi_set_named_property(env, object, name.c_str(), jsValue);
172 }
173 
174 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)175 napi_value NapiPrintUtils::CreateStringUtf8(napi_env env, const std::string &str)
176 {
177     napi_value value = nullptr;
178     if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
179         return nullptr;
180     }
181     return value;
182 }
183 
GetStringFromValueUtf8(napi_env env,napi_value value)184 std::string NapiPrintUtils::GetStringFromValueUtf8(napi_env env, napi_value value)
185 {
186     std::string result;
187     std::vector<char> str(MAX_STRING_LENGTH + 1, '\0');
188     size_t length = 0;
189     PRINT_CALL_BASE(env, napi_get_value_string_utf8(env, value, &str[0], MAX_STRING_LENGTH, &length), result);
190     if (length > 0) {
191         return result.append(&str[0], length);
192     }
193     return result;
194 }
195 
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)196 std::string NapiPrintUtils::GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
197 {
198     if (!HasNamedProperty(env, object, propertyName)) {
199         return "";
200     }
201     napi_value value = GetNamedProperty(env, object, propertyName);
202     return GetStringFromValueUtf8(env, value);
203 }
204 
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)205 void NapiPrintUtils::SetStringPropertyUtf8(
206     napi_env env, napi_value object, const std::string &name, const std::string &value)
207 {
208     napi_value jsValue = CreateStringUtf8(env, value);
209     if (GetValueType(env, jsValue) != napi_string) {
210         return;
211     }
212     napi_set_named_property(env, object, name.c_str(), jsValue);
213 }
214 
215 /* array buffer */
216 
CreateArrayBuffer(napi_env env,size_t length,void ** data)217 napi_value NapiPrintUtils::CreateArrayBuffer(napi_env env, size_t length, void **data)
218 {
219     napi_value object = nullptr;
220     PRINT_CALL(env, napi_create_arraybuffer(env, length, data, &object));
221     return object;
222 }
223 
ValueIsArrayBuffer(napi_env env,napi_value value)224 bool NapiPrintUtils::ValueIsArrayBuffer(napi_env env, napi_value value)
225 {
226     bool isArrayBuffer = false;
227     PRINT_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
228     return isArrayBuffer;
229 }
230 
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)231 void *NapiPrintUtils::GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
232 {
233     if (length == nullptr) {
234         return nullptr;
235     }
236 
237     void *data = nullptr;
238     PRINT_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
239     return data;
240 }
241 
242 /* object */
CreateObject(napi_env env)243 napi_value NapiPrintUtils::CreateObject(napi_env env)
244 {
245     napi_value object = nullptr;
246     PRINT_CALL(env, napi_create_object(env, &object));
247     return object;
248 }
249 
250 /* undefined */
GetUndefined(napi_env env)251 napi_value NapiPrintUtils::GetUndefined(napi_env env)
252 {
253     napi_value undefined = nullptr;
254     PRINT_CALL(env, napi_get_undefined(env, &undefined));
255     return undefined;
256 }
257 
258 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)259 napi_value NapiPrintUtils::CallFunction(
260     napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
261 {
262     napi_value res = nullptr;
263     PRINT_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
264     return res;
265 }
266 
CreateFunction(napi_env env,const std::string & name,napi_callback func,void * arg)267 napi_value NapiPrintUtils::CreateFunction
268     (napi_env env, const std::string &name, napi_callback func, void *arg)
269 {
270     napi_value res = nullptr;
271     PRINT_CALL(env, napi_create_function(env, name.c_str(), NAPI_AUTO_LENGTH, func, arg, &res));
272     return res;
273 }
274 
275 /* reference */
CreateReference(napi_env env,napi_value callback)276 napi_ref NapiPrintUtils::CreateReference(napi_env env, napi_value callback)
277 {
278     napi_ref callbackRef = nullptr;
279     PRINT_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
280     return callbackRef;
281 }
282 
GetReference(napi_env env,napi_ref callbackRef)283 napi_value NapiPrintUtils::GetReference(napi_env env, napi_ref callbackRef)
284 {
285     napi_value callback = nullptr;
286     PRINT_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
287     return callback;
288 }
289 
DeleteReference(napi_env env,napi_ref callbackRef)290 void NapiPrintUtils::DeleteReference(napi_env env, napi_ref callbackRef)
291 {
292     (void)napi_delete_reference(env, callbackRef);
293 }
294 
295 /* boolean */
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)296 bool NapiPrintUtils::GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
297 {
298     if (!HasNamedProperty(env, object, propertyName)) {
299         return false;
300     }
301     napi_value value = GetNamedProperty(env, object, propertyName);
302     bool ret = false;
303     PRINT_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
304     return ret;
305 }
306 
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)307 void NapiPrintUtils::SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
308 {
309     napi_value jsValue = nullptr;
310     PRINT_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
311     if (GetValueType(env, jsValue) != napi_boolean) {
312         return;
313     }
314 
315     napi_set_named_property(env, object, name.c_str(), jsValue);
316 }
317 
318 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)319 void NapiPrintUtils::DefineProperties(
320     napi_env env, napi_value object, const std::initializer_list<napi_property_descriptor> &properties)
321 {
322     std::vector<napi_property_descriptor> descriptors(properties.begin(), properties.end());
323 
324     (void)napi_define_properties(env, object, properties.size(), descriptors.data());
325 }
326 
GetValueString(napi_env env,napi_value value)327 std::string NapiPrintUtils::GetValueString(napi_env env, napi_value value)
328 {
329     std::string resultValue = "";
330     char value_string[256] = { 0 };
331     size_t value_size = 256;
332     size_t result = 0;
333     napi_status status = napi_get_value_string_utf8(env, value, value_string, value_size, &result);
334     if (status == napi_ok && result > 0) {
335         resultValue = value_string;
336     }
337     return resultValue;
338 }
339 
GetJsVal(napi_env env,napi_callback_info info,napi_value argv[],size_t length)340 size_t NapiPrintUtils::GetJsVal(napi_env env, napi_callback_info info, napi_value argv[], size_t length)
341 {
342     size_t argc = length;
343     napi_value thisVal = nullptr;
344     void *data = nullptr;
345     napi_get_cb_info(env, info, &argc, argv, &thisVal, &data);
346     return argc;
347 }
348 
VerifyProperty(std::vector<std::string> & names,std::map<std::string,PrintParamStatus> & propertyList)349 bool NapiPrintUtils::VerifyProperty(
350     std::vector<std::string> &names, std::map<std::string, PrintParamStatus> &propertyList)
351 {
352     for (const auto& name : names) {
353         if (propertyList.find(name) == propertyList.end()) {
354             PRINT_HILOGE("Invalid property: %{public}s", name.c_str());
355             return false;
356         }
357         propertyList[name] = PRINT_PARAM_SET;
358     }
359 
360     for (const auto& propertyItem : propertyList) {
361         if (propertyItem.second == PRINT_PARAM_NOT_SET) {
362             PRINT_HILOGE("Missing Property: %{public}s", propertyItem.first.c_str());
363             return false;
364         }
365     }
366     return true;
367 }
368 
GetPrintErrorMsg(int32_t errorCode)369 std::string NapiPrintUtils::GetPrintErrorMsg(int32_t errorCode)
370 {
371     auto msg = PRINT_ERROR_MSG_MAP.find(static_cast<PrintErrorCode>(errorCode));
372     if (msg != PRINT_ERROR_MSG_MAP.end()) {
373         return msg->second;
374     }
375     return "";
376 }
377 
CheckCallerIsSystemApp()378 bool NapiPrintUtils::CheckCallerIsSystemApp()
379 {
380     auto callerToken = IPCSkeleton::GetCallingTokenID();
381     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callerToken);
382     if (tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_NATIVE ||
383         tokenType == Security::AccessToken::ATokenTypeEnum::TOKEN_SHELL) {
384         PRINT_HILOGD("tokenType check passed.");
385         return true;
386     }
387     auto accessTokenId = IPCSkeleton::GetCallingFullTokenID();
388     return Security::AccessToken::TokenIdKit::IsSystemAppByFullTokenID(accessTokenId);
389 }
390 
GetErrorMsgByErrorCode(int32_t code)391 const std::string NapiPrintUtils::GetErrorMsgByErrorCode(int32_t code)
392 {
393     PRINT_HILOGD("GetErrorMsgByErrorCode start");
394     auto iter = ERROR_CODE_CONVERT_MESSAGE_MAP.find(code);
395     if (iter == ERROR_CODE_CONVERT_MESSAGE_MAP.end()) {
396         PRINT_HILOGE("error is out of definition.");
397         return ERROR_MESSAGE_OUT_OF_DEFINITION;
398     }
399     PRINT_HILOGD("ErrorMessage: %{public}s", (iter->second).c_str());
400     return iter->second;
401 }
402 
CreateJsError(napi_env env,int32_t errCode)403 napi_value NapiPrintUtils::CreateJsError(napi_env env, int32_t errCode)
404 {
405     std::string errMsg = GetErrorMsgByErrorCode(errCode);
406     PRINT_HILOGD("CreateJsError errCode: %{public}d, errMsg: %{public}s", errCode, errMsg.c_str());
407 
408     napi_value code = nullptr;
409     napi_status status = napi_create_int32(env, errCode, &code);
410     if (status != napi_ok) {
411         PRINT_HILOGE("napi create error code failed");
412         return nullptr;
413     }
414 
415     napi_value message = nullptr;
416     status = napi_create_string_utf8(env, errMsg.c_str(), NAPI_AUTO_LENGTH, &message);
417     if (status != napi_ok) {
418         PRINT_HILOGE("napi create error message failed");
419         return nullptr;
420     }
421 
422     napi_value errorObj = nullptr;
423     status = napi_create_error(env, code, message, &errorObj);
424     if (status != napi_ok) {
425         PRINT_HILOGE("napi create js error failed");
426         return nullptr;
427     }
428 
429     return errorObj;
430 }
431 }  // namespace OHOS::Print
432