• 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_scan_utils.h"
17 
18 #include <fcntl.h>
19 #include "ability.h"
20 #include "napi_base_context.h"
21 #include "scan_log.h"
22 #include "securec.h"
23 
24 namespace OHOS::Scan {
25 static constexpr const int MAX_STRING_LENGTH = 65536;
26 const std::string GLOBAL_ID_DELIMITER = ":";
27 const std::string EXTENSION_CID_DELIMITER = ":";
28 const std::string TASK_EVENT_DELIMITER = "-";
29 
GetValueType(napi_env env,napi_value value)30 napi_valuetype NapiScanUtils::GetValueType(napi_env env, napi_value value)
31 {
32     if (value == nullptr) {
33         return napi_undefined;
34     }
35 
36     napi_valuetype valueType = napi_undefined;
37     SCAN_CALL_BASE(env, napi_typeof(env, value, &valueType), napi_undefined);
38     return valueType;
39 }
40 
41 /* named property */
HasNamedProperty(napi_env env,napi_value object,const std::string & propertyName)42 bool NapiScanUtils::HasNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
43 {
44     bool hasProperty = false;
45     SCAN_CALL_BASE(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty), false);
46     return hasProperty;
47 }
48 
GetNamedProperty(napi_env env,napi_value object,const std::string & propertyName)49 napi_value NapiScanUtils::GetNamedProperty(napi_env env, napi_value object, const std::string &propertyName)
50 {
51     napi_value value = nullptr;
52     bool hasProperty = false;
53     SCAN_CALL(env, napi_has_named_property(env, object, propertyName.c_str(), &hasProperty));
54     if (!hasProperty) {
55         return value;
56     }
57     SCAN_CALL(env, napi_get_named_property(env, object, propertyName.c_str(), &value));
58     return value;
59 }
60 
SetNamedProperty(napi_env env,napi_value object,const std::string & name,napi_value value)61 void NapiScanUtils::SetNamedProperty(napi_env env, napi_value object, const std::string &name, napi_value value)
62 {
63     (void)napi_set_named_property(env, object, name.c_str(), value);
64 }
65 
GetPropertyNames(napi_env env,napi_value object)66 std::vector<std::string> NapiScanUtils::GetPropertyNames(napi_env env, napi_value object)
67 {
68     std::vector<std::string> ret;
69     napi_value names = nullptr;
70     SCAN_CALL_BASE(env, napi_get_property_names(env, object, &names), ret);
71     uint32_t length = 0;
72     SCAN_CALL_BASE(env, napi_get_array_length(env, names, &length), ret);
73     for (uint32_t index = 0; index < length; ++index) {
74         napi_value name = nullptr;
75         if (napi_get_element(env, names, index, &name) != napi_ok) {
76             continue;
77         }
78         if (GetValueType(env, name) != napi_string) {
79             continue;
80         }
81         ret.emplace_back(GetStringFromValueUtf8(env, name));
82     }
83     return ret;
84 }
85 
86 /* UINT32 */
CreateUint32(napi_env env,uint32_t code)87 napi_value NapiScanUtils::CreateUint32(napi_env env, uint32_t code)
88 {
89     napi_value value = nullptr;
90     if (napi_create_uint32(env, code, &value) != napi_ok) {
91         return nullptr;
92     }
93     return value;
94 }
95 
GetUint32FromValue(napi_env env,napi_value value)96 uint32_t NapiScanUtils::GetUint32FromValue(napi_env env, napi_value value)
97 {
98     uint32_t ret = 0;
99     SCAN_CALL_BASE(env, napi_get_value_uint32(env, value, &ret), 0);
100     return ret;
101 }
102 
GetUint32Property(napi_env env,napi_value object,const std::string & propertyName)103 uint32_t NapiScanUtils::GetUint32Property(napi_env env, napi_value object, const std::string &propertyName)
104 {
105     if (!HasNamedProperty(env, object, propertyName)) {
106         return 0;
107     }
108     napi_value value = GetNamedProperty(env, object, propertyName);
109     return GetUint32FromValue(env, value);
110 }
111 
SetUint32Property(napi_env env,napi_value object,const std::string & name,uint32_t value)112 void NapiScanUtils::SetUint32Property(napi_env env, napi_value object, const std::string &name, uint32_t value)
113 {
114     napi_value jsValue = CreateUint32(env, value);
115     if (GetValueType(env, jsValue) != napi_number) {
116         return;
117     }
118 
119     napi_set_named_property(env, object, name.c_str(), jsValue);
120 }
121 
122 /* INT32 */
CreateInt32(napi_env env,int32_t code)123 napi_value NapiScanUtils::CreateInt32(napi_env env, int32_t code)
124 {
125     napi_value value = nullptr;
126     if (napi_create_int32(env, code, &value) != napi_ok) {
127         return nullptr;
128     }
129     return value;
130 }
131 
GetInt32FromValue(napi_env env,napi_value value)132 int32_t NapiScanUtils::GetInt32FromValue(napi_env env, napi_value value)
133 {
134     int32_t ret = 0;
135     SCAN_CALL_BASE(env, napi_get_value_int32(env, value, &ret), 0);
136     return ret;
137 }
138 
GetInt32Property(napi_env env,napi_value object,const std::string & propertyName)139 int32_t NapiScanUtils::GetInt32Property(napi_env env, napi_value object, const std::string &propertyName)
140 {
141     if (!HasNamedProperty(env, object, propertyName)) {
142         return 0;
143     }
144     napi_value value = GetNamedProperty(env, object, propertyName);
145     return GetInt32FromValue(env, value);
146 }
147 
SetInt32Property(napi_env env,napi_value object,const std::string & name,int32_t value)148 void NapiScanUtils::SetInt32Property(napi_env env, napi_value object, const std::string &name, int32_t value)
149 {
150     napi_value jsValue = CreateInt32(env, value);
151     if (GetValueType(env, jsValue) != napi_number) {
152         return;
153     }
154 
155     napi_set_named_property(env, object, name.c_str(), jsValue);
156 }
157 
158 /* String UTF8 */
CreateStringUtf8(napi_env env,const std::string & str)159 napi_value NapiScanUtils::CreateStringUtf8(napi_env env, const std::string &str)
160 {
161     napi_value value = nullptr;
162     if (napi_create_string_utf8(env, str.c_str(), strlen(str.c_str()), &value) != napi_ok) {
163         return nullptr;
164     }
165     return value;
166 }
167 
GetStringFromValueUtf8(napi_env env,napi_value value)168 std::string NapiScanUtils::GetStringFromValueUtf8(napi_env env, napi_value value)
169 {
170     std::string result;
171     std::vector<char> str(MAX_STRING_LENGTH + 1, '\0');
172     size_t length = 0;
173     SCAN_CALL_BASE(env, napi_get_value_string_utf8(env, value, &str[0], MAX_STRING_LENGTH, &length), result);
174     if (length > 0) {
175         return result.append(&str[0], length);
176     }
177     return result;
178 }
179 
GetStringPropertyUtf8(napi_env env,napi_value object,const std::string & propertyName)180 std::string NapiScanUtils::GetStringPropertyUtf8(napi_env env, napi_value object, const std::string &propertyName)
181 {
182     if (!HasNamedProperty(env, object, propertyName)) {
183         return "";
184     }
185     napi_value value = GetNamedProperty(env, object, propertyName);
186     return GetStringFromValueUtf8(env, value);
187 }
188 
SetStringPropertyUtf8(napi_env env,napi_value object,const std::string & name,const std::string & value)189 void NapiScanUtils::SetStringPropertyUtf8(
190     napi_env env, napi_value object, const std::string &name, const std::string &value)
191 {
192     napi_value jsValue = CreateStringUtf8(env, value);
193     if (GetValueType(env, jsValue) != napi_string) {
194         return;
195     }
196     napi_set_named_property(env, object, name.c_str(), jsValue);
197 }
198 
199 /* array buffer */
200 
CreateArrayBuffer(napi_env env,size_t length,void ** data)201 napi_value NapiScanUtils::CreateArrayBuffer(napi_env env, size_t length, void **data)
202 {
203     napi_value object = nullptr;
204     SCAN_CALL(env, napi_create_arraybuffer(env, length, data, &object));
205     return object;
206 }
207 
ValueIsArrayBuffer(napi_env env,napi_value value)208 bool NapiScanUtils::ValueIsArrayBuffer(napi_env env, napi_value value)
209 {
210     bool isArrayBuffer = false;
211     SCAN_CALL_BASE(env, napi_is_arraybuffer(env, value, &isArrayBuffer), false);
212     return isArrayBuffer;
213 }
214 
GetInfoFromArrayBufferValue(napi_env env,napi_value value,size_t * length)215 void *NapiScanUtils::GetInfoFromArrayBufferValue(napi_env env, napi_value value, size_t *length)
216 {
217     if (length == nullptr) {
218         return nullptr;
219     }
220 
221     void *data = nullptr;
222     SCAN_CALL(env, napi_get_arraybuffer_info(env, value, &data, length));
223     return data;
224 }
225 
226 /* object */
CreateObject(napi_env env)227 napi_value NapiScanUtils::CreateObject(napi_env env)
228 {
229     napi_value object = nullptr;
230     SCAN_CALL(env, napi_create_object(env, &object));
231     return object;
232 }
233 
234 /* undefined */
GetUndefined(napi_env env)235 napi_value NapiScanUtils::GetUndefined(napi_env env)
236 {
237     napi_value undefined = nullptr;
238     SCAN_CALL(env, napi_get_undefined(env, &undefined));
239     return undefined;
240 }
241 
242 /* function */
CallFunction(napi_env env,napi_value recv,napi_value func,size_t argc,const napi_value * argv)243 napi_value NapiScanUtils::CallFunction(
244     napi_env env, napi_value recv, napi_value func, size_t argc, const napi_value *argv)
245 {
246     napi_value res = nullptr;
247     SCAN_CALL(env, napi_call_function(env, recv, func, argc, argv, &res));
248     return res;
249 }
250 
251 /* reference */
CreateReference(napi_env env,napi_value callback)252 napi_ref NapiScanUtils::CreateReference(napi_env env, napi_value callback)
253 {
254     napi_ref callbackRef = nullptr;
255     SCAN_CALL(env, napi_create_reference(env, callback, 1, &callbackRef));
256     return callbackRef;
257 }
258 
GetReference(napi_env env,napi_ref callbackRef)259 napi_value NapiScanUtils::GetReference(napi_env env, napi_ref callbackRef)
260 {
261     napi_value callback = nullptr;
262     SCAN_CALL(env, napi_get_reference_value(env, callbackRef, &callback));
263     return callback;
264 }
265 
DeleteReference(napi_env env,napi_ref callbackRef)266 void NapiScanUtils::DeleteReference(napi_env env, napi_ref callbackRef)
267 {
268     if (env != nullptr && callbackRef != nullptr) {
269         (void)napi_delete_reference(env, callbackRef);
270     }
271 }
272 
273 /* boolean */
CreateBoolean(napi_env env,bool value)274 napi_value NapiScanUtils::CreateBoolean(napi_env env, bool value)
275 {
276     napi_value jsValue = nullptr;
277     if (napi_get_boolean(env, value, &jsValue) != napi_ok) {
278         return nullptr;
279     }
280     return jsValue;
281 }
282 
GetBooleanFromValue(napi_env env,napi_value value)283 bool NapiScanUtils::GetBooleanFromValue(napi_env env, napi_value value)
284 {
285     bool ret = 0;
286     SCAN_CALL_BASE(env, napi_get_value_bool(env, value, &ret), 0);
287     return ret;
288 }
289 
GetBooleanProperty(napi_env env,napi_value object,const std::string & propertyName)290 bool NapiScanUtils::GetBooleanProperty(napi_env env, napi_value object, const std::string &propertyName)
291 {
292     if (!HasNamedProperty(env, object, propertyName)) {
293         return false;
294     }
295     napi_value value = GetNamedProperty(env, object, propertyName);
296     bool ret = false;
297     SCAN_CALL_BASE(env, napi_get_value_bool(env, value, &ret), false);
298     return ret;
299 }
300 
SetBooleanProperty(napi_env env,napi_value object,const std::string & name,bool value)301 void NapiScanUtils::SetBooleanProperty(napi_env env, napi_value object, const std::string &name, bool value)
302 {
303     napi_value jsValue = nullptr;
304     SCAN_CALL_RETURN_VOID(env, napi_get_boolean(env, value, &jsValue));
305     if (GetValueType(env, jsValue) != napi_boolean) {
306         return;
307     }
308 
309     napi_set_named_property(env, object, name.c_str(), jsValue);
310 }
311 
312 /* define properties */
DefineProperties(napi_env env,napi_value object,const std::initializer_list<napi_property_descriptor> & properties)313 void NapiScanUtils::DefineProperties(
314     napi_env env, napi_value object, const std::initializer_list<napi_property_descriptor> &properties)
315 {
316     napi_property_descriptor descriptors[properties.size()];
317     std::copy(properties.begin(), properties.end(), descriptors);
318 
319     (void)napi_define_properties(env, object, properties.size(), descriptors);
320 }
321 
ToLower(const std::string & s)322 std::string NapiScanUtils::ToLower(const std::string &s)
323 {
324     std::string res = s;
325     std::transform(res.begin(), res.end(), res.begin(), tolower);
326     return res;
327 }
328 
GetValueString(napi_env env,napi_value value)329 std::string NapiScanUtils::GetValueString(napi_env env, napi_value value)
330 {
331     std::string resultValue = "";
332     char value_string[256];
333     size_t value_size = 256;
334     size_t result;
335     napi_get_value_string_utf8(env, value, value_string, value_size, &result);
336     resultValue = value_string;
337     return resultValue;
338 }
339 
GetExtensionId(const std::string & globalId)340 std::string NapiScanUtils::GetExtensionId(const std::string &globalId)
341 {
342     auto pos = globalId.find(GLOBAL_ID_DELIMITER);
343     if (pos == std::string::npos) {
344         return "";
345     }
346     return globalId.substr(0, pos);
347 }
348 
GetGlobalId(const std::string & extensionId,const std::string & localId)349 std::string NapiScanUtils::GetGlobalId(const std::string& extensionId, const std::string& localId)
350 {
351     return extensionId + GLOBAL_ID_DELIMITER + localId;
352 }
353 
GetLocalId(const std::string & globalId,const std::string & extensionId)354 std::string NapiScanUtils::GetLocalId(const std::string& globalId, const std::string& extensionId)
355 {
356     auto pos = globalId.find(GLOBAL_ID_DELIMITER);
357     if (pos == std::string::npos) {
358         return "";
359     }
360 
361     if (globalId.substr(0, pos) != extensionId) {
362         return "";
363     }
364     return globalId.substr(pos + 1);
365 }
366 
EncodeExtensionCid(const std::string & extensionId,uint32_t callbackId)367 std::string NapiScanUtils::EncodeExtensionCid(const std::string &extensionId, uint32_t callbackId)
368 {
369     return extensionId + EXTENSION_CID_DELIMITER + std::to_string(callbackId);
370 }
371 
DecodeExtensionCid(const std::string & cid,std::string & extensionId,uint32_t & callbackId)372 bool NapiScanUtils::DecodeExtensionCid(const std::string &cid, std::string &extensionId, uint32_t &callbackId)
373 {
374     auto pos = cid.find(EXTENSION_CID_DELIMITER);
375     if (pos == std::string::npos) {
376         return false;
377     }
378     extensionId = cid.substr(0, pos);
379     callbackId = static_cast<uint32_t>(atoi(cid.substr(pos + 1).c_str()));
380     return true;
381 }
382 
GetTaskEventId(const std::string & taskId,const std::string & type)383 std::string NapiScanUtils::GetTaskEventId(const std::string &taskId, const std::string &type)
384 {
385     return type + TASK_EVENT_DELIMITER + taskId;
386 }
387 
OpenFile(const std::string & filePath)388 int32_t NapiScanUtils::OpenFile(const std::string &filePath)
389 {
390     if (!IsPathValid(filePath)) {
391         return SCAN_INVALID_ID;
392     }
393     char realFilePath[PATH_MAX] = {};
394     if (realpath(filePath.c_str(), realFilePath) == nullptr) {
395         SCAN_HILOGE("The realFilePath is null.");
396         return SCAN_INVALID_ID;
397     }
398     int32_t fd = open(realFilePath, O_RDONLY);
399     SCAN_HILOGD("fd: %{public}d", fd);
400     if (fd < 0) {
401         SCAN_HILOGE("Failed to open file errno: %{public}s", std::to_string(errno).c_str());
402         return SCAN_INVALID_ID;
403     }
404     return fd;
405 }
406 
IsPathValid(const std::string & filePath)407 bool NapiScanUtils::IsPathValid(const std::string &filePath)
408 {
409     auto path = filePath.substr(0, filePath.rfind('/'));
410     char resolvedPath[PATH_MAX + 1] = { 0 };
411     if (path.length() > PATH_MAX || realpath(path.c_str(), resolvedPath) == nullptr ||
412         strncmp(resolvedPath, path.c_str(), path.length()) != 0) {
413         SCAN_HILOGE("invalid file path!");
414         return false;
415     }
416     return true;
417 }
418 
GetIdFromFdPath(const std::string & fdPath)419 uint32_t NapiScanUtils::GetIdFromFdPath(const std::string &fdPath)
420 {
421     std::string fd_str = fdPath.substr(fdPath.rfind('/') + 1, fdPath.length());
422     std::stringstream getStrStream(fd_str);
423     uint32_t fd;
424     if (!(getStrStream >> fd)) {
425         SCAN_HILOGD("failed to convert to uint32");
426     }
427     return fd;
428 }
429 
GetJsVal(napi_env env,napi_callback_info info,napi_value argv[],size_t length)430 size_t NapiScanUtils::GetJsVal(napi_env env, napi_callback_info info, napi_value argv[], size_t length)
431 {
432     size_t argc = length;
433     napi_value thisVal = nullptr;
434     void *data = nullptr;
435     napi_get_cb_info(env, info, &argc, argv, &thisVal, &data);
436     return argc;
437 }
438 
439 } // namespace OHOS::Scan
440