1 /*
2  * Copyright (c) 2024 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_message_parcel.h"
17 #include <cstring>
18 #include <unistd.h>
19 #include "hilog/log.h"
20 #include "log_tags.h"
21 #include "napi_ashmem.h"
22 #include "napi_remote_object.h"
23 #include "napi_rpc_common.h"
24 #include "string_ex.h"
25 #include "ipc_debug.h"
26 
27 
28 namespace OHOS {
29 static constexpr OHOS::HiviewDFX::HiLogLabel LOG_LABEL = { LOG_CORE, LOG_ID_IPC_NAPI, "Napi_MessageParcelRead" };
30 
JS_readRemoteObject(napi_env env,napi_callback_info info)31 napi_value NAPI_MessageParcel::JS_readRemoteObject(napi_env env, napi_callback_info info)
32 {
33     size_t argc = 0;
34     napi_value thisVar = nullptr;
35     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
36 
37     NAPI_MessageParcel *napiParcel = nullptr;
38     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
39     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
40 
41     sptr<IRemoteObject> value = napiParcel->nativeParcel_->ReadRemoteObject();
42     napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
43     return napiValue;
44 }
45 
JS_readInterfaceToken(napi_env env,napi_callback_info info)46 napi_value NAPI_MessageParcel::JS_readInterfaceToken(napi_env env, napi_callback_info info)
47 {
48     size_t argc = 0;
49     napi_value thisVar = nullptr;
50     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
51 
52     NAPI_MessageParcel *napiParcel = nullptr;
53     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
54     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
55 
56     std::u16string parcelString = napiParcel->nativeParcel_->ReadInterfaceToken();
57     std::string outString = Str16ToStr8(parcelString.c_str());
58     napi_value napiValue = nullptr;
59     napi_create_string_utf8(env, outString.c_str(), outString.length(), &napiValue);
60     return napiValue;
61 }
62 
JS_readException(napi_env env,napi_callback_info info)63 napi_value NAPI_MessageParcel::JS_readException(napi_env env, napi_callback_info info)
64 {
65     napi_value result = nullptr;
66     napi_get_undefined(env, &result);
67     napi_value thisVar = nullptr;
68     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr);
69     NAPI_MessageParcel *napiParcel = nullptr;
70     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
71     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
72 
73     int32_t code = napiParcel->nativeParcel_->ReadInt32();
74     if (code == 0) {
75         return result;
76     }
77     std::u16string str = napiParcel->nativeParcel_->ReadString16();
78     napi_throw_error(env, nullptr, Str16ToStr8(str).c_str());
79     return result;
80 }
81 
JS_readByte(napi_env env,napi_callback_info info)82 napi_value NAPI_MessageParcel::JS_readByte(napi_env env, napi_callback_info info)
83 {
84     size_t argc = 0;
85     napi_value thisVar = nullptr;
86     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
87     NAPI_MessageParcel *napiParcel = nullptr;
88     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
89     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
90 
91     int8_t value = napiParcel->nativeParcel_->ReadInt8();
92     napi_value napiValue = nullptr;
93     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
94     return napiValue;
95 }
96 
JS_readShort(napi_env env,napi_callback_info info)97 napi_value NAPI_MessageParcel::JS_readShort(napi_env env, napi_callback_info info)
98 {
99     size_t argc = 0;
100     napi_value thisVar = nullptr;
101     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
102     NAPI_MessageParcel *napiParcel = nullptr;
103     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
104     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
105 
106     int16_t value = napiParcel->nativeParcel_->ReadInt16();
107     napi_value napiValue = nullptr;
108     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
109     return napiValue;
110 }
111 
JS_readInt(napi_env env,napi_callback_info info)112 napi_value NAPI_MessageParcel::JS_readInt(napi_env env, napi_callback_info info)
113 {
114     size_t argc = 0;
115     napi_value thisVar = nullptr;
116     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
117     NAPI_MessageParcel *napiParcel = nullptr;
118     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
119     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
120 
121     int32_t value = napiParcel->nativeParcel_->ReadInt32();
122     napi_value napiValue = nullptr;
123     NAPI_CALL(env, napi_create_int32(env, value, &napiValue));
124     return napiValue;
125 }
126 
JS_readLong(napi_env env,napi_callback_info info)127 napi_value NAPI_MessageParcel::JS_readLong(napi_env env, napi_callback_info info)
128 {
129     size_t argc = 0;
130     napi_value thisVar = nullptr;
131     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
132     NAPI_MessageParcel *napiParcel = nullptr;
133     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
134     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
135 
136     int64_t value = napiParcel->nativeParcel_->ReadInt64();
137     napi_value napiValue = nullptr;
138     NAPI_CALL(env, napi_create_int64(env, value, &napiValue));
139     return napiValue;
140 }
141 
JS_readFloat(napi_env env,napi_callback_info info)142 napi_value NAPI_MessageParcel::JS_readFloat(napi_env env, napi_callback_info info)
143 {
144     size_t argc = 0;
145     napi_value thisVar = nullptr;
146     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
147     NAPI_MessageParcel *napiParcel = nullptr;
148     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
149     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
150 
151     double value = napiParcel->nativeParcel_->ReadDouble();
152     napi_value napiValue = nullptr;
153     NAPI_CALL(env, napi_create_double(env, value, &napiValue));
154     return napiValue;
155 }
156 
JS_readDouble(napi_env env,napi_callback_info info)157 napi_value NAPI_MessageParcel::JS_readDouble(napi_env env, napi_callback_info info)
158 {
159     size_t argc = 0;
160     napi_value thisVar = nullptr;
161     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
162     NAPI_MessageParcel *napiParcel = nullptr;
163     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
164     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
165 
166     double value = napiParcel->nativeParcel_->ReadDouble();
167     napi_value napiValue = nullptr;
168     NAPI_CALL(env, napi_create_double(env, value, &napiValue));
169     return napiValue;
170 }
171 
JS_readBoolean(napi_env env,napi_callback_info info)172 napi_value NAPI_MessageParcel::JS_readBoolean(napi_env env, napi_callback_info info)
173 {
174     size_t argc = 0;
175     napi_value thisVar = nullptr;
176     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
177     NAPI_MessageParcel *napiParcel = nullptr;
178     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
179     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
180 
181     int8_t value = napiParcel->nativeParcel_->ReadInt8();
182     napi_value napiValue = nullptr;
183     NAPI_CALL(env, napi_get_boolean(env, value, &napiValue));
184     return napiValue;
185 }
186 
JS_readChar(napi_env env,napi_callback_info info)187 napi_value NAPI_MessageParcel::JS_readChar(napi_env env, napi_callback_info info)
188 {
189     size_t argc = 0;
190     napi_value thisVar = nullptr;
191     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
192     NAPI_MessageParcel *napiParcel = nullptr;
193     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
194     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
195 
196     uint8_t value = napiParcel->nativeParcel_->ReadUint8();
197     napi_value result = nullptr;
198     napi_create_uint32(env, static_cast<uint32_t>(value), &result);
199     return result;
200 }
201 
JS_readString(napi_env env,napi_callback_info info)202 napi_value NAPI_MessageParcel::JS_readString(napi_env env, napi_callback_info info)
203 {
204     size_t argc = 0;
205     napi_value thisVar = nullptr;
206     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
207     NAPI_MessageParcel *napiParcel = nullptr;
208     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
209     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
210 
211     std::u16string parcelString = napiParcel->nativeParcel_->ReadString16();
212     std::string outString = Str16ToStr8(parcelString.c_str());
213     napi_value napiValue = nullptr;
214     napi_create_string_utf8(env, outString.c_str(), outString.length(), &napiValue);
215     return napiValue;
216 }
217 
JS_readSequenceable(napi_env env,napi_callback_info info)218 napi_value NAPI_MessageParcel::JS_readSequenceable(napi_env env, napi_callback_info info)
219 {
220     size_t argc = 1;
221     napi_value argv[ARGV_LENGTH_1] = {0};
222     napi_value thisVar = nullptr;
223     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
224     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
225 
226     NAPI_MessageParcel *napiParcel = nullptr;
227     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
228     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
229 
230     int32_t len = napiParcel->nativeParcel_->ReadInt32();
231     if (len > 0) {
232         napi_value propKey = nullptr;
233         const char *propKeyStr = "unmarshalling";
234         napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
235         napi_value prop = nullptr;
236         napi_get_property(env, argv[ARGV_INDEX_0], propKey, &prop);
237 
238         napi_value funcArg[1] = {thisVar};
239         napi_value callResult = nullptr;
240         napi_call_function(env, argv[ARGV_INDEX_0], prop, 1, funcArg, &callResult);
241         if (callResult != nullptr) {
242             return callResult;
243         }
244         ZLOGI(LOG_LABEL, "call unmarshalling failed");
245     }
246 
247     napi_value napiValue = nullptr;
248     NAPI_CALL(env, napi_get_boolean(env, false, &napiValue));
249     return napiValue;
250 }
251 
JS_readByteArray(napi_env env,napi_callback_info info)252 napi_value NAPI_MessageParcel::JS_readByteArray(napi_env env, napi_callback_info info)
253 {
254     size_t argc = 0;
255     napi_value thisVar = nullptr;
256     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
257 
258     NAPI_MessageParcel *napiParcel = nullptr;
259     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
260     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
261 
262     uint32_t maxBytesLen = 40960;
263     uint32_t arrayLength = napiParcel->nativeParcel_->ReadUint32();
264     NAPI_ASSERT(env, arrayLength < maxBytesLen, "byte array length too large");
265 
266     if (argc > 0) {
267         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
268         napi_value argv[ARGV_LENGTH_1] = {0};
269         void *data = nullptr;
270         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
271 
272         bool isArray = false;
273         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
274         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
275 
276         for (uint32_t i = 0; i < arrayLength; i++) {
277             int8_t val = napiParcel->nativeParcel_->ReadInt8();
278             napi_value num = nullptr;
279             napi_create_int32(env, val, &num);
280             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
281         }
282         napi_value napiValue = nullptr;
283         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
284         return napiValue;
285     }
286 
287     if (arrayLength == 0) {
288         napi_value result = nullptr;
289         napi_create_array(env, &result);
290         return result;
291     }
292     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiParcel);
293     napi_value result = nullptr;
294     napi_create_array_with_length(env, (size_t)arrayLength, &result);
295 
296     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
297         int8_t val = napiParcel->nativeParcel_->ReadInt8();
298         napi_value num = nullptr;
299         napi_create_int32(env, val, &num);
300         napi_set_element(env, result, i, num);
301     }
302     return result;
303 }
304 
JS_readShortArray(napi_env env,napi_callback_info info)305 napi_value NAPI_MessageParcel::JS_readShortArray(napi_env env, napi_callback_info info)
306 {
307     size_t argc = 0;
308     napi_value thisVar = nullptr;
309     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
310 
311     NAPI_MessageParcel *napiParcel = nullptr;
312     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
313     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
314 
315     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
316     if (argc > 0) {
317         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
318         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
319         napi_value argv[ARGV_LENGTH_1] = {0};
320         void *data = nullptr;
321         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
322 
323         bool isArray = false;
324         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
325         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
326 
327         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
328             int16_t val = napiParcel->nativeParcel_->ReadInt16();
329             napi_value num = nullptr;
330             napi_create_int32(env, val, &num);
331             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
332         }
333         napi_value napiValue = nullptr;
334         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
335         return napiValue;
336     }
337 
338     if (arrayLength <= 0) {
339         napi_value result = nullptr;
340         napi_create_array(env, &result);
341         return result;
342     }
343     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
344     napi_value result = nullptr;
345     napi_create_array_with_length(env, (size_t)arrayLength, &result);
346 
347     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
348         int16_t val = napiParcel->nativeParcel_->ReadInt16();
349         napi_value num = nullptr;
350         napi_create_int32(env, val, &num);
351         napi_set_element(env, result, i, num);
352     }
353     return result;
354 }
355 
JS_readIntArray(napi_env env,napi_callback_info info)356 napi_value NAPI_MessageParcel::JS_readIntArray(napi_env env, napi_callback_info info)
357 {
358     size_t argc = 0;
359     napi_value thisVar = nullptr;
360     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
361 
362     NAPI_MessageParcel *napiParcel = nullptr;
363     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
364     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
365 
366     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
367     if (argc > 0) {
368         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
369         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
370         napi_value argv[ARGV_LENGTH_1] = {0};
371         void *data = nullptr;
372         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
373 
374         bool isArray = false;
375         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
376         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
377 
378         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
379             int32_t val = napiParcel->nativeParcel_->ReadInt32();
380             napi_value num = nullptr;
381             napi_create_int32(env, val, &num);
382             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
383         }
384         napi_value napiValue = nullptr;
385         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
386         return napiValue;
387     }
388 
389     if (arrayLength <= 0) {
390         napi_value result = nullptr;
391         napi_create_array(env, &result);
392         return result;
393     }
394     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
395     napi_value result = nullptr;
396     napi_create_array_with_length(env, (size_t)arrayLength, &result);
397 
398     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
399         int32_t val = napiParcel->nativeParcel_->ReadInt32();
400         napi_value num = nullptr;
401         napi_create_int32(env, val, &num);
402         napi_set_element(env, result, i, num);
403     }
404     return result;
405 }
406 
JS_readLongArray(napi_env env,napi_callback_info info)407 napi_value NAPI_MessageParcel::JS_readLongArray(napi_env env, napi_callback_info info)
408 {
409     size_t argc = 0;
410     napi_value thisVar = nullptr;
411     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
412 
413     NAPI_MessageParcel *napiParcel = nullptr;
414     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
415     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
416 
417     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
418     if (argc > 0) {
419         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
420         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_64, napiParcel);
421         napi_value argv[ARGV_LENGTH_1] = {0};
422         void *data = nullptr;
423         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
424 
425         bool isArray = false;
426         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
427         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
428 
429         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
430             int64_t val = napiParcel->nativeParcel_->ReadInt64();
431             napi_value num = nullptr;
432             napi_create_int64(env, val, &num);
433             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
434         }
435         napi_value napiValue = nullptr;
436         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
437         return napiValue;
438     }
439 
440     if (arrayLength <= 0) {
441         napi_value result = nullptr;
442         napi_create_array(env, &result);
443         return result;
444     }
445     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_64, napiParcel);
446     napi_value result = nullptr;
447     napi_create_array_with_length(env, (size_t)arrayLength, &result);
448 
449     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
450         int64_t val = napiParcel->nativeParcel_->ReadInt64();
451         napi_value num = nullptr;
452         napi_create_int64(env, val, &num);
453         napi_set_element(env, result, i, num);
454     }
455     return result;
456 }
457 
JS_readFloatArray(napi_env env,napi_callback_info info)458 napi_value NAPI_MessageParcel::JS_readFloatArray(napi_env env, napi_callback_info info)
459 {
460     size_t argc = 0;
461     napi_value thisVar = nullptr;
462     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
463 
464     NAPI_MessageParcel *napiParcel = nullptr;
465     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
466     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
467 
468     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
469     if (argc > 0) {
470         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
471         CHECK_READ_LENGTH(env, (size_t)arrayLength, sizeof(double), napiParcel);
472         napi_value argv[ARGV_LENGTH_1] = {0};
473         void *data = nullptr;
474         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
475 
476         bool isArray = false;
477         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
478         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
479 
480         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
481             double val = napiParcel->nativeParcel_->ReadDouble();
482             napi_value num = nullptr;
483             napi_create_double(env, val, &num);
484             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
485         }
486         napi_value napiValue = nullptr;
487         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
488         return napiValue;
489     }
490 
491     if (arrayLength <= 0) {
492         napi_value result = nullptr;
493         napi_create_array(env, &result);
494         return result;
495     }
496     CHECK_READ_LENGTH(env, (size_t)arrayLength, sizeof(double), napiParcel);
497     napi_value result = nullptr;
498     napi_create_array_with_length(env, (size_t)arrayLength, &result);
499 
500     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
501         double val = napiParcel->nativeParcel_->ReadDouble();
502         napi_value num = nullptr;
503         napi_create_double(env, val, &num);
504         napi_set_element(env, result, i, num);
505     }
506     return result;
507 }
508 
JS_readDoubleArray(napi_env env,napi_callback_info info)509 napi_value NAPI_MessageParcel::JS_readDoubleArray(napi_env env, napi_callback_info info)
510 {
511     size_t argc = 0;
512     napi_value thisVar = nullptr;
513     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
514 
515     NAPI_MessageParcel *napiParcel = nullptr;
516     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
517     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
518 
519     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
520     if (argc > 0) {
521         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
522         CHECK_READ_LENGTH(env, (size_t)arrayLength, sizeof(double), napiParcel);
523         napi_value argv[ARGV_LENGTH_1] = {0};
524         void *data = nullptr;
525         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
526 
527         bool isArray = false;
528         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
529         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
530 
531         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
532             double val = napiParcel->nativeParcel_->ReadDouble();
533             napi_value num = nullptr;
534             napi_create_double(env, val, &num);
535             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
536         }
537         napi_value napiValue = nullptr;
538         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
539         return napiValue;
540     }
541 
542     if (arrayLength <= 0) {
543         napi_value result = nullptr;
544         napi_create_array(env, &result);
545         return result;
546     }
547     CHECK_READ_LENGTH(env, (size_t)arrayLength, sizeof(double), napiParcel);
548     napi_value result = nullptr;
549     napi_create_array_with_length(env, (size_t)arrayLength, &result);
550 
551     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
552         double val = napiParcel->nativeParcel_->ReadDouble();
553         napi_value num = nullptr;
554         napi_create_double(env, val, &num);
555         napi_set_element(env, result, i, num);
556     }
557     return result;
558 }
559 
JS_readBooleanArray(napi_env env,napi_callback_info info)560 napi_value NAPI_MessageParcel::JS_readBooleanArray(napi_env env, napi_callback_info info)
561 {
562     size_t argc = 0;
563     napi_value thisVar = nullptr;
564     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
565 
566     NAPI_MessageParcel *napiParcel = nullptr;
567     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
568     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
569 
570     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
571     if (argc > 0) {
572         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
573         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
574         napi_value argv[ARGV_LENGTH_1] = {0};
575         void *data = nullptr;
576         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
577 
578         bool isArray = false;
579         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
580         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
581 
582         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
583             int8_t val = napiParcel->nativeParcel_->ReadInt8();
584             napi_value boolean = nullptr;
585             napi_get_boolean(env, val, &boolean);
586             napi_set_element(env, argv[ARGV_INDEX_0], i, boolean);
587         }
588         napi_value napiValue = nullptr;
589         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
590         return napiValue;
591     }
592 
593     if (arrayLength <= 0) {
594         napi_value result = nullptr;
595         napi_create_array(env, &result);
596         return result;
597     }
598 
599     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
600     napi_value result = nullptr;
601     napi_create_array_with_length(env, (size_t)arrayLength, &result);
602 
603     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
604         int8_t val = napiParcel->nativeParcel_->ReadInt8();
605         napi_value boolean = nullptr;
606         napi_get_boolean(env, val, &boolean);
607         napi_set_element(env, result, i, boolean);
608     }
609     return result;
610 }
611 
JS_readCharArray(napi_env env,napi_callback_info info)612 napi_value NAPI_MessageParcel::JS_readCharArray(napi_env env, napi_callback_info info)
613 {
614     size_t argc = 0;
615     napi_value thisVar = nullptr;
616     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
617 
618     NAPI_MessageParcel *napiParcel = nullptr;
619     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
620     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
621 
622     uint32_t arrayLength = napiParcel->nativeParcel_->ReadUint32();
623     if (argc > 0) {
624         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
625         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
626         napi_value argv[ARGV_LENGTH_1] = {0};
627         void *data = nullptr;
628         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
629 
630         bool isArray = false;
631         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
632         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
633 
634         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
635             uint8_t val = napiParcel->nativeParcel_->ReadUint8();
636             napi_value num = nullptr;
637             napi_create_uint32(env, static_cast<uint32_t>(val), &num);
638             napi_set_element(env, argv[ARGV_INDEX_0], i, num);
639         }
640         napi_value napiValue = nullptr;
641         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
642         return napiValue;
643     }
644 
645     if (arrayLength == 0) {
646         napi_value result = nullptr;
647         napi_create_array(env, &result);
648         return result;
649     }
650     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
651     napi_value result = nullptr;
652     napi_create_array_with_length(env, (size_t)arrayLength, &result);
653 
654     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
655         uint8_t val = napiParcel->nativeParcel_->ReadUint8();
656         napi_value num = nullptr;
657         napi_create_uint32(env, static_cast<uint32_t>(val), &num);
658         napi_set_element(env, result, i, num);
659     }
660     return result;
661 }
662 
JS_readStringArray(napi_env env,napi_callback_info info)663 napi_value NAPI_MessageParcel::JS_readStringArray(napi_env env, napi_callback_info info)
664 {
665     size_t argc = 0;
666     napi_value thisVar = nullptr;
667     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
668 
669     NAPI_MessageParcel *napiParcel = nullptr;
670     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
671     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
672 
673     uint32_t arrayLength = napiParcel->nativeParcel_->ReadUint32();
674     if (argc > 0) {
675         NAPI_ASSERT(env, argc == 1, "type mismatch for parameter 1");
676         CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
677         napi_value argv[ARGV_LENGTH_1] = {0};
678         void *data = nullptr;
679         napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
680 
681         bool isArray = false;
682         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
683         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
684 
685         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
686             if (napiParcel->nativeParcel_->GetReadableBytes() <= 0) {
687                 break;
688             }
689             std::u16string parcelString = napiParcel->nativeParcel_->ReadString16();
690             std::string outString = Str16ToStr8(parcelString.c_str());
691             napi_value val = nullptr;
692             napi_create_string_utf8(env, outString.c_str(), outString.length(), &val);
693             napi_set_element(env, argv[ARGV_INDEX_0], i, val);
694         }
695         napi_value napiValue = nullptr;
696         NAPI_CALL(env, napi_get_boolean(env, true, &napiValue));
697         return napiValue;
698     }
699 
700     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_32, napiParcel);
701     napi_value result = nullptr;
702     napi_create_array(env, &result);
703     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
704         if (napiParcel->nativeParcel_->GetReadableBytes() <= 0) {
705             break;
706         }
707         std::u16string parcelString = napiParcel->nativeParcel_->ReadString16();
708         std::string outString = Str16ToStr8(parcelString.c_str());
709         napi_value val = nullptr;
710         napi_create_string_utf8(env, outString.c_str(), outString.length(), &val);
711         napi_set_element(env, result, i, val);
712     }
713     return result;
714 }
715 
JS_readSequenceableArray(napi_env env,napi_callback_info info)716 napi_value NAPI_MessageParcel::JS_readSequenceableArray(napi_env env, napi_callback_info info)
717 {
718     size_t argc = 1;
719     napi_value thisVar = nullptr;
720     napi_value argv[ARGV_LENGTH_1] = { 0 };
721     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
722     NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
723 
724     NAPI_MessageParcel *napiParcel = nullptr;
725     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
726     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
727 
728     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
729     // checking here is not accurate, but we can defend some extreme attacking case.
730     CHECK_READ_LENGTH(env, (size_t)arrayLength, BYTE_SIZE_8, napiParcel);
731 
732     bool isArray = false;
733     napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
734     NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
735     uint32_t length = 0;
736     napi_get_array_length(env, argv[ARGV_INDEX_0], &length);
737     if (static_cast<int32_t>(length) != arrayLength) {
738         napi_value result = nullptr;
739         napi_get_undefined(env, &result);
740         napi_throw_error(env, nullptr, "Bad length while reading Sequenceable array");
741         return result;
742     }
743 
744     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
745         int32_t len = napiParcel->nativeParcel_->ReadInt32();
746         if (len > 0) {
747             bool hasElement = false;
748             napi_has_element(env, argv[ARGV_INDEX_0], i, &hasElement);
749             NAPI_ASSERT(env, hasElement == true, "parameter check error");
750             napi_value element = nullptr;
751             napi_get_element(env, argv[ARGV_INDEX_0], i, &element);
752 
753             napi_value propKey = nullptr;
754             const char *propKeyStr = "unmarshalling";
755             napi_create_string_utf8(env, propKeyStr, strlen(propKeyStr), &propKey);
756             napi_value prop = nullptr;
757             napi_get_property(env, element, propKey, &prop);
758 
759             napi_value funcArg[1] = { thisVar };
760             napi_value callResult = nullptr;
761             napi_call_function(env, element, prop, 1, funcArg, &callResult);
762             if (callResult == nullptr) {
763                 ZLOGE(LOG_LABEL, "call unmarshalling failed, element index:%{public}d", i);
764                 break;
765             }
766         }
767     }
768     napi_value result = nullptr;
769     napi_get_undefined(env, &result);
770     return result;
771 }
772 
JS_readRemoteObjectArray(napi_env env,napi_callback_info info)773 napi_value NAPI_MessageParcel::JS_readRemoteObjectArray(napi_env env, napi_callback_info info)
774 {
775     napi_value result = nullptr;
776     napi_get_undefined(env, &result);
777 
778     size_t argc = 0;
779     napi_value argv[ARGV_LENGTH_1] = { 0 };
780     napi_value thisVar = nullptr;
781     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
782 
783     NAPI_MessageParcel *napiParcel = nullptr;
784     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
785     NAPI_ASSERT(env, napiParcel != nullptr, "napiParcel is null");
786 
787     int32_t arrayLength = napiParcel->nativeParcel_->ReadInt32();
788     if (argc > 0) { // uses passed in array
789         NAPI_ASSERT(env, argc == 1, "requires 1 parameter");
790         napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
791         bool isArray = false;
792         napi_is_array(env, argv[ARGV_INDEX_0], &isArray);
793         NAPI_ASSERT(env, isArray == true, "type mismatch for parameter 1");
794         uint32_t length = 0;
795         napi_get_array_length(env, argv[ARGV_INDEX_0], &length);
796         if (static_cast<int32_t>(length) != arrayLength) {
797             return result;
798         }
799         for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
800             sptr<IRemoteObject> value = napiParcel->nativeParcel_->ReadRemoteObject();
801             napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
802             napi_set_element(env, argv[ARGV_INDEX_0], i, napiValue);
803         }
804         return result;
805     }
806 
807     if (arrayLength <= 0) {
808         napi_get_null(env, &result);
809         return result;
810     }
811     napi_create_array(env, &result);
812     for (uint32_t i = 0; i < (uint32_t)arrayLength; i++) {
813         sptr<IRemoteObject> value = napiParcel->nativeParcel_->ReadRemoteObject();
814         napi_value napiValue = NAPI_ohos_rpc_CreateJsRemoteObject(env, value);
815         napi_set_element(env, result, i, napiValue);
816     }
817     return result;
818 }
819 
JS_ReadFileDescriptor(napi_env env,napi_callback_info info)820 napi_value NAPI_MessageParcel::JS_ReadFileDescriptor(napi_env env, napi_callback_info info)
821 {
822     size_t argc = 0;
823     napi_value thisVar = nullptr;
824     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
825     NAPI_MessageParcel *napiParcel = nullptr;
826     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
827     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
828     int32_t result = napiParcel->nativeParcel_->ReadFileDescriptor();
829     napi_value napiValue;
830     napi_create_int32(env, result, &napiValue);
831     return napiValue;
832 }
833 
JS_ReadAshmem(napi_env env,napi_callback_info info)834 napi_value NAPI_MessageParcel::JS_ReadAshmem(napi_env env, napi_callback_info info)
835 {
836     size_t argc = 0;
837     napi_value thisVar = nullptr;
838     napi_get_cb_info(env, info, &argc, nullptr, &thisVar, nullptr);
839 
840     NAPI_MessageParcel *napiParcel = nullptr;
841     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
842     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
843     sptr<Ashmem> nativeAshmem = napiParcel->nativeParcel_->ReadAshmem();
844     napi_value global = nullptr;
845     napi_status status = napi_get_global(env, &global);
846     NAPI_ASSERT(env, status == napi_ok, "get napi global failed");
847     napi_value constructor = nullptr;
848     status = napi_get_named_property(env, global, "AshmemConstructor_", &constructor);
849     NAPI_ASSERT(env, status == napi_ok, "get Ashmem constructor failed");
850     napi_value jsAshmem;
851     status = napi_new_instance(env, constructor, 0, nullptr, &jsAshmem);
852     NAPI_ASSERT(env, status == napi_ok, "failed to  construct js Ashmem");
853     NAPIAshmem *napiAshmem = nullptr;
854     napi_unwrap(env, jsAshmem, reinterpret_cast<void **>(&napiAshmem));
855     NAPI_ASSERT(env, napiAshmem != nullptr, "napiAshmem is null");
856     napiAshmem->SetAshmem(nativeAshmem);
857     return jsAshmem;
858 }
859 
JS_ReadRawData(napi_env env,napi_callback_info info)860 napi_value NAPI_MessageParcel::JS_ReadRawData(napi_env env, napi_callback_info info)
861 {
862     size_t argc = 1;
863     napi_value argv[ARGV_LENGTH_1] = { 0 };
864     napi_value thisVar = nullptr;
865     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
866     NAPI_ASSERT(env, argc == 1, "requires 1 parameters");
867     napi_valuetype valueType = napi_null;
868     napi_typeof(env, argv[ARGV_INDEX_0], &valueType);
869     NAPI_ASSERT(env, valueType == napi_number, "type mismatch for parameter 1");
870     int32_t arraySize = 0;
871     napi_get_value_int32(env, argv[ARGV_INDEX_0], &arraySize);
872     NAPI_MessageParcel *napiParcel = nullptr;
873     napi_unwrap(env, thisVar, reinterpret_cast<void **>(&napiParcel));
874     NAPI_ASSERT_BASE(env, napiParcel != nullptr, "napiParcel is null", nullptr);
875     const void *rawData = napiParcel->nativeParcel_->ReadRawData(arraySize * BYTE_SIZE_32);
876     NAPI_ASSERT_BASE(env, rawData != nullptr, "rawData is null", nullptr);
877     // [c++] rawData -> byteBuffer()[js]
878     napi_value result = nullptr;
879     if (arraySize <= 0) {
880         napi_create_array(env, &result);
881         return result;
882     }
883     napi_create_array_with_length(env, (size_t)arraySize, &result);
884     const int32_t *ptr = static_cast<const int32_t *>(rawData);
885     for (uint32_t i = 0; i < (uint32_t)arraySize; i++) {
886         napi_value num = nullptr;
887         napi_create_int32(env, ptr[i], &num);
888         napi_set_element(env, result, i, num);
889     }
890     return result;
891 }
892 } // namespace OHOS
893