• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "common_func.h"
17 
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <memory>
21 #include <sstream>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <vector>
26 
27 #include "app_log_wrapper.h"
28 #include "gzip_entity.h"
29 #include "napi_class.h"
30 #include "napi_business_error.h"
31 #include "zip_entity.h"
32 
33 namespace OHOS {
34 namespace AppExecFwk {
35 namespace LIBZIP {
36 static constexpr uint8_t MIN_NUMBER = 1;
37 static constexpr uint8_t MIN_ASCII = 0;
38 static constexpr uint8_t MAX_ASCII = 255;
39 static constexpr uint8_t MIN_WINDOWBITS = 8;
40 static constexpr uint8_t MAX_WINDOWBITS = 15;
41 
GetAdler32Arg(napi_env env,const NapiFuncArg & funcArg)42 std::tuple<bool, int64_t, void *, size_t> CommonFunc::GetAdler32Arg(napi_env env, const NapiFuncArg &funcArg)
43 {
44     bool succ = false;
45     int64_t adler = 0U;
46 
47     // The first argument
48     NapiValue adlerNVal(env, funcArg[ArgumentPosition::FIRST]);
49     std::tie(succ, adler) = adlerNVal.ToInt64();
50     if (!succ) {
51         NapiBusinessError().ThrowErr(env, EINVAL);
52         return {false, 0, nullptr, 0};
53     }
54 
55     // The second argument
56     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
57     void *buf = nullptr;
58     size_t bufLen = 0;
59     std::tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
60     if (!succ) {
61         NapiBusinessError().ThrowErr(env, EINVAL);
62         return {false, 0, nullptr, 0};
63     }
64 
65     return {true, adler, buf, bufLen};
66 }
67 
GetCrc64Arg(napi_env env,const NapiFuncArg & funcArg)68 std::tuple<bool, int64_t, void *, size_t> CommonFunc::GetCrc64Arg(napi_env env, const NapiFuncArg &funcArg)
69 {
70     bool succ = false;
71     int64_t crc64 = 0U;
72 
73     // The first argument
74     NapiValue crc64NVal(env, funcArg[ArgumentPosition::FIRST]);
75     std::tie(succ, crc64) = crc64NVal.ToInt64();
76     if (!succ) {
77         NapiBusinessError().ThrowErr(env, EINVAL);
78         return {false, 0, nullptr, 0};
79     }
80 
81     // The second argument
82     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
83     void *buf = nullptr;
84     size_t bufLen = 0;
85     std::tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
86     if (!succ) {
87         NapiBusinessError().ThrowErr(env, EINVAL);
88         return {false, 0, nullptr, 0};
89     }
90 
91     return {true, crc64, buf, bufLen};
92 }
93 
GetAdler32CombineArg(napi_env env,const NapiFuncArg & funcArg)94 std::tuple<bool, unsigned long, unsigned long, int64_t> CommonFunc::GetAdler32CombineArg(
95     napi_env env, const NapiFuncArg &funcArg)
96 {
97     bool succ = false;
98     uint64_t adler1 = 0U;
99     uint64_t adler2 = 0U;
100     int64_t len = 0;
101 
102     NapiValue adler1NVal(env, funcArg[ArgumentPosition::FIRST]);
103     std::tie(succ, adler1) = adler1NVal.ToInt64();
104     if (!succ) {
105         NapiBusinessError().ThrowErr(env, EINVAL);
106         return {false, 0, 0, 0};
107     }
108 
109     NapiValue adler2NVal(env, funcArg[ArgumentPosition::SECOND]);
110     std::tie(succ, adler2) = adler2NVal.ToInt64();
111     if (!succ) {
112         NapiBusinessError().ThrowErr(env, EINVAL);
113         return {false, 0, 0, 0};
114     }
115 
116     NapiValue bufLenNVal(env, funcArg[ArgumentPosition::THIRD]);
117     std::tie(succ, len) = bufLenNVal.ToInt64();
118     if (!succ || len < 0) {
119         NapiBusinessError().ThrowErr(env, EINVAL);
120         return {false, 0, 0, 0};
121     }
122     return {true, adler1, adler2, len};
123 }
124 
SetZStreamOutValue(const HasZStreamMember & hasZStreamMember,ZipEntity * zipEntity,const z_stream & zs)125 static void SetZStreamOutValue(const HasZStreamMember &hasZStreamMember, ZipEntity *zipEntity, const z_stream &zs)
126 {
127     if (hasZStreamMember.hasNextOut) {
128         zipEntity->zs.get()->next_out = zs.next_out;
129     }
130     if (hasZStreamMember.hasAvailOut) {
131         zipEntity->zs.get()->avail_out = zs.avail_out;
132     }
133     if (hasZStreamMember.hasTotalOut) {
134         zipEntity->zs.get()->total_out = zs.total_out;
135     }
136     if (hasZStreamMember.hasDataType) {
137         zipEntity->zs.get()->data_type = zs.data_type;
138     }
139     if (hasZStreamMember.hasAdler) {
140         zipEntity->zs.get()->adler = zs.adler;
141     }
142 }
143 
SetZStreamValue(napi_env env,const NapiFuncArg & funcArg)144 bool CommonFunc::SetZStreamValue(napi_env env, const NapiFuncArg &funcArg)
145 {
146     /* To get entity */
147     auto zipEntity = NapiClass::GetEntityOf<ZipEntity>(env, funcArg.GetThisVar());
148     if (!zipEntity) {
149         NapiBusinessError().ThrowErr(env, EFAULT);
150         return false;
151     }
152 
153     bool succ = false;
154     z_stream zs = {};
155     HasZStreamMember hasZStreamMember;
156     std::tie(succ, zs, hasZStreamMember) = CommonFunc::GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
157     if (!succ) {
158         NapiBusinessError().ThrowErr(env, EINVAL);
159         return succ;
160     }
161 
162     if (!zipEntity->zs) {
163         zipEntity->zs = std::make_unique<z_stream>();
164     }
165 
166     if (hasZStreamMember.hasNextIn) {
167         zipEntity->zs.get()->next_in = zs.next_in;
168     }
169     if (hasZStreamMember.hasAvailIn) {
170         zipEntity->zs.get()->avail_in = zs.avail_in;
171     }
172     if (hasZStreamMember.hasTotalIn) {
173         zipEntity->zs.get()->total_in = zs.total_in;
174     }
175 
176     SetZStreamOutValue(hasZStreamMember, zipEntity, zs);
177     return succ;
178 }
179 
GetZStreamInValue(napi_env env,NapiValue zstreamNVal,HasZStreamMember & hasZStreamMember,z_stream & zs)180 static bool GetZStreamInValue(napi_env env, NapiValue zstreamNVal, HasZStreamMember &hasZStreamMember, z_stream &zs)
181 {
182     bool succ = false;
183     if (zstreamNVal.HasProp("nextIn") && !zstreamNVal.GetProp("nextIn").TypeIs(napi_undefined) &&
184         !zstreamNVal.GetProp("nextIn").TypeIs(napi_null)) {
185         void *buf = nullptr;
186         size_t bufLen = 0;
187         std::tie(succ, buf, bufLen) = zstreamNVal.GetProp("nextIn").ToArrayBuffer();
188         if (!succ) {
189             NapiBusinessError().ThrowErr(env, EINVAL);
190             return false;
191         }
192         zs.next_in = reinterpret_cast<Bytef *>(buf);
193         hasZStreamMember.hasNextIn = true;
194     }
195 
196     if (zstreamNVal.HasProp("availableIn") && !zstreamNVal.GetProp("availableIn").TypeIs(napi_undefined) &&
197         !zstreamNVal.GetProp("availableIn").TypeIs(napi_null)) {
198         uint32_t availableIn = 0U;
199         std::tie(succ, availableIn) = zstreamNVal.GetProp("availableIn").ToInt32();
200         if (!succ) {
201             NapiBusinessError().ThrowErr(env, EINVAL);
202             return false;
203         }
204         zs.avail_in = availableIn;
205         hasZStreamMember.hasAvailIn = true;
206     }
207 
208     if (zstreamNVal.HasProp("totalIn") && !zstreamNVal.GetProp("totalIn").TypeIs(napi_undefined) &&
209         !zstreamNVal.GetProp("totalIn").TypeIs(napi_null)) {
210         uint64_t totalIn = 0U;
211         std::tie(succ, totalIn) = zstreamNVal.GetProp("totalIn").ToInt64();
212         if (!succ) {
213             NapiBusinessError().ThrowErr(env, EINVAL);
214             return false;
215         }
216         zs.total_in = totalIn;
217         hasZStreamMember.hasTotalIn = true;
218     }
219 
220     return true;
221 }
222 
GetZStreamOtherValue(napi_env env,NapiValue zstreamNVal,HasZStreamMember & hasZStreamMember,z_stream & zs)223 static bool GetZStreamOtherValue(napi_env env, NapiValue zstreamNVal, HasZStreamMember &hasZStreamMember, z_stream &zs)
224 {
225     bool succ = false;
226     if (zstreamNVal.HasProp("dataType") && !zstreamNVal.GetProp("dataType").TypeIs(napi_undefined) &&
227         !zstreamNVal.GetProp("dataType").TypeIs(napi_null)) {
228         int32_t dataType = 0;
229         std::tie(succ, dataType) = zstreamNVal.GetProp("dataType").ToInt32();
230         if (!succ) {
231             NapiBusinessError().ThrowErr(env, EINVAL);
232             return false;
233         }
234         zs.data_type = dataType;
235         hasZStreamMember.hasDataType = true;
236     }
237 
238     if (zstreamNVal.HasProp("adler") && !zstreamNVal.GetProp("adler").TypeIs(napi_undefined) &&
239         !zstreamNVal.GetProp("adler").TypeIs(napi_null)) {
240         uint64_t adler = 0;
241         std::tie(succ, adler) = zstreamNVal.GetProp("adler").ToInt64();
242         if (!succ) {
243             NapiBusinessError().ThrowErr(env, EINVAL);
244             return false;
245         }
246         zs.adler = adler;
247         hasZStreamMember.hasAdler = true;
248     }
249 
250     return true;
251 }
252 
GetZstreamArg(napi_env env,napi_value zstream)253 std::tuple<bool, z_stream, HasZStreamMember> CommonFunc::GetZstreamArg(napi_env env, napi_value zstream)
254 {
255     z_stream zs = {};
256     bool succ = false;
257     NapiValue zstreamNVal(env, zstream);
258     HasZStreamMember hasZStreamMember = {};
259 
260     if (zstreamNVal.TypeIs(napi_undefined) || zstreamNVal.TypeIs(napi_null)) {
261         NapiBusinessError().ThrowErr(env, EINVAL);
262         return { false, {}, {} };
263     }
264 
265     succ = GetZStreamInValue(env, zstreamNVal, hasZStreamMember, zs);
266     if (!succ) {
267         NapiBusinessError().ThrowErr(env, EINVAL);
268         return { false, {}, {} };
269     }
270 
271     if (zstreamNVal.HasProp("nextOut") && !zstreamNVal.GetProp("nextOut").TypeIs(napi_undefined) &&
272         !zstreamNVal.GetProp("nextOut").TypeIs(napi_null)) {
273         void *buf = nullptr;
274         size_t bufLen = 0;
275         std::tie(succ, buf, bufLen) = zstreamNVal.GetProp("nextOut").ToArrayBuffer();
276         if (!succ) {
277             NapiBusinessError().ThrowErr(env, EINVAL);
278             return {false, {}, {}};
279         }
280         zs.next_out = reinterpret_cast<Bytef *>(buf);
281         hasZStreamMember.hasNextOut = true;
282     }
283 
284     if (zstreamNVal.HasProp("availableOut") && !zstreamNVal.GetProp("availableOut").TypeIs(napi_undefined) &&
285         !zstreamNVal.GetProp("availableOut").TypeIs(napi_null)) {
286         uint32_t availableOut = 0U;
287         std::tie(succ, availableOut) = zstreamNVal.GetProp("availableOut").ToInt32();
288         if (!succ) {
289             NapiBusinessError().ThrowErr(env, EINVAL);
290             return {false, {}, {}};
291         }
292         zs.avail_out = availableOut;
293         hasZStreamMember.hasAvailOut = true;
294     }
295 
296     if (zstreamNVal.HasProp("totalOut") && !zstreamNVal.GetProp("totalOut").TypeIs(napi_undefined) &&
297         !zstreamNVal.GetProp("totalOut").TypeIs(napi_null)) {
298         uint64_t totalOut = 0U;
299         std::tie(succ, totalOut) = zstreamNVal.GetProp("totalOut").ToInt64();
300         if (!succ) {
301             NapiBusinessError().ThrowErr(env, EINVAL);
302             return {false, {}, {}};
303         }
304         zs.total_out = totalOut;
305         hasZStreamMember.hasTotalOut = true;
306     }
307 
308     succ = GetZStreamOtherValue(env, zstreamNVal, hasZStreamMember, zs);
309     if (!succ) {
310         NapiBusinessError().ThrowErr(env, EINVAL);
311         return { false, {}, {} };
312     }
313 
314     return {true, zs, hasZStreamMember};
315 }
316 
GetGZHeadValue(napi_env env,const NapiValue & gzHeaderNVal,gz_header & gzHeader)317 static bool GetGZHeadValue(napi_env env, const NapiValue &gzHeaderNVal, gz_header &gzHeader)
318 {
319     bool succ = false;
320     if (gzHeaderNVal.HasProp("isText") && !gzHeaderNVal.GetProp("isText").TypeIs(napi_undefined) &&
321         !gzHeaderNVal.GetProp("isText").TypeIs(napi_null)) {
322         bool text = false;
323         std::tie(succ, text) = gzHeaderNVal.GetProp("isText").ToBool();
324         if (!succ) {
325             NapiBusinessError().ThrowErr(env, EINVAL);
326             return false;
327         }
328         gzHeader.text = text;
329     }
330 
331     if (gzHeaderNVal.HasProp("time") && !gzHeaderNVal.GetProp("time").TypeIs(napi_undefined) &&
332         !gzHeaderNVal.GetProp("time").TypeIs(napi_null)) {
333         uint64_t time = 0U;
334         std::tie(succ, time) = gzHeaderNVal.GetProp("time").ToInt64();
335         if (!succ) {
336             NapiBusinessError().ThrowErr(env, EINVAL);
337             return false;
338         }
339         gzHeader.time = time;
340     }
341 
342     if (gzHeaderNVal.HasProp("xflags") && !gzHeaderNVal.GetProp("xflags").TypeIs(napi_undefined) &&
343         !gzHeaderNVal.GetProp("xflags").TypeIs(napi_null)) {
344         int32_t xflags = 0;
345         std::tie(succ, xflags) = gzHeaderNVal.GetProp("xflags").ToInt32();
346         if (!succ) {
347             NapiBusinessError().ThrowErr(env, EINVAL);
348             return false;
349         }
350         gzHeader.xflags = xflags;
351     }
352 
353     if (gzHeaderNVal.HasProp("os") && !gzHeaderNVal.GetProp("os").TypeIs(napi_undefined) &&
354         !gzHeaderNVal.GetProp("os").TypeIs(napi_null)) {
355         int32_t os = 0;
356         std::tie(succ, os) = gzHeaderNVal.GetProp("os").ToInt32();
357         if (!succ) {
358             NapiBusinessError().ThrowErr(env, EINVAL);
359             return false;
360         }
361         gzHeader.os = os;
362     }
363     return true;
364 }
365 
UnwrapGZHeadValue(napi_env env,NapiValue & gzHeaderNVal,gz_header & gzHeader)366 static bool UnwrapGZHeadValue(napi_env env, NapiValue &gzHeaderNVal, gz_header &gzHeader)
367 {
368     bool succ = false;
369     if (gzHeaderNVal.HasProp("extra") && !gzHeaderNVal.GetProp("extra").TypeIs(napi_undefined) &&
370         !gzHeaderNVal.GetProp("extra").TypeIs(napi_null)) {
371         void *extra = nullptr;
372         size_t extraLen = 0;
373         std::tie(succ, extra, extraLen) = gzHeaderNVal.GetProp("extra").ToArrayBuffer();
374         if (!succ) {
375             NapiBusinessError().ThrowErr(env, EINVAL);
376             return false;
377         }
378         gzHeader.extra = reinterpret_cast<Bytef *>(extra);
379     }
380 
381     if (gzHeaderNVal.HasProp("done") && !gzHeaderNVal.GetProp("done").TypeIs(napi_undefined) &&
382         !gzHeaderNVal.GetProp("done").TypeIs(napi_null)) {
383         bool done = false;
384         std::tie(succ, done) = gzHeaderNVal.GetProp("done").ToBool();
385         if (!succ) {
386             NapiBusinessError().ThrowErr(env, EINVAL);
387             return false;
388         }
389         gzHeader.done = done;
390     }
391 
392     if (gzHeaderNVal.HasProp("hcrc") && !gzHeaderNVal.GetProp("hcrc").TypeIs(napi_undefined) &&
393         !gzHeaderNVal.GetProp("hcrc").TypeIs(napi_null)) {
394         bool hcrc = false;
395         std::tie(succ, hcrc) = gzHeaderNVal.GetProp("hcrc").ToBool();
396         if (!succ) {
397             NapiBusinessError().ThrowErr(env, EINVAL);
398             return false;
399         }
400         gzHeader.hcrc = hcrc;
401     }
402 
403     return true;
404 }
405 
GetGZHeaderArg(napi_env env,napi_value argGZheader)406 std::tuple<bool, gz_header> CommonFunc::GetGZHeaderArg(napi_env env, napi_value argGZheader)
407 {
408     bool succ = false;
409     NapiValue gzHeaderNVal(env, argGZheader);
410     gz_header gzHeader = {};
411 
412     if (gzHeaderNVal.TypeIs(napi_undefined) || gzHeaderNVal.TypeIs(napi_null)) {
413         NapiBusinessError().ThrowErr(env, EINVAL);
414         return { false, {}};
415     }
416 
417     succ = GetGZHeadValue(env, gzHeaderNVal, gzHeader);
418     if (!succ) {
419         NapiBusinessError().ThrowErr(env, EINVAL);
420         return { false, {} };
421     }
422 
423     if (gzHeaderNVal.HasProp("extraLen") && !gzHeaderNVal.GetProp("extraLen").TypeIs(napi_undefined) &&
424         !gzHeaderNVal.GetProp("extraLen").TypeIs(napi_null)) {
425         uint32_t extraLen = 0U;
426         std::tie(succ, extraLen) = gzHeaderNVal.GetProp("extraLen").ToInt32();
427         if (!succ) {
428             NapiBusinessError().ThrowErr(env, EINVAL);
429             return {false, {}};
430         }
431         gzHeader.extra_len = extraLen;
432     }
433 
434     if (gzHeaderNVal.HasProp("name") && !gzHeaderNVal.GetProp("name").TypeIs(napi_undefined) &&
435         !gzHeaderNVal.GetProp("name").TypeIs(napi_null)) {
436         void *name = nullptr;
437         size_t nameLen = 0;
438         std::tie(succ, name, nameLen) = gzHeaderNVal.GetProp("name").ToArrayBuffer();
439         if (!succ) {
440             NapiBusinessError().ThrowErr(env, EINVAL);
441             return {false, {}};
442         }
443         gzHeader.name = reinterpret_cast<Bytef *>(name);
444     }
445 
446     if (gzHeaderNVal.HasProp("comment") && !gzHeaderNVal.GetProp("comment").TypeIs(napi_undefined) &&
447         !gzHeaderNVal.GetProp("comment").TypeIs(napi_null)) {
448         void *comment = nullptr;
449         size_t commentLen = 0;
450         std::tie(succ, comment, commentLen) = gzHeaderNVal.GetProp("comment").ToArrayBuffer();
451         if (!succ) {
452             NapiBusinessError().ThrowErr(env, EINVAL);
453             return {false, {}};
454         }
455         gzHeader.comment = reinterpret_cast<Bytef *>(comment);
456     }
457 
458     succ = UnwrapGZHeadValue(env, gzHeaderNVal, gzHeader);
459     if (!succ) {
460         NapiBusinessError().ThrowErr(env, EINVAL);
461         return { false, {} };
462     }
463 
464     return {true, gzHeader};
465 }
466 
GetInflateInitArg(napi_env env,const NapiFuncArg & funcArg)467 std::tuple<bool, z_stream, int32_t> CommonFunc::GetInflateInitArg(napi_env env, const NapiFuncArg &funcArg)
468 {
469     bool succ = false;
470 
471     // The first argument
472     z_stream zs = {};
473     HasZStreamMember hasZStreamMember = {};
474     std::tie(succ, zs, hasZStreamMember) = GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
475     if (!succ) {
476         NapiBusinessError().ThrowErr(env, EINVAL);
477         return {false, {}, 0};
478     }
479 
480     // The second argument
481     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
482     int32_t windowBits = 0;
483     std::tie(succ, windowBits) = bufNVal.ToInt32();
484     if (!succ) {
485         NapiBusinessError().ThrowErr(env, EINVAL);
486         return {false, {}, 0};
487     }
488 
489     return {true, zs, windowBits};
490 }
491 
GetDeflateInitArg(napi_env env,const NapiFuncArg & funcArg)492 std::tuple<bool, z_stream, int32_t> CommonFunc::GetDeflateInitArg(napi_env env, const NapiFuncArg &funcArg)
493 {
494     bool succ = false;
495 
496     // The first argument
497     z_stream zs = {};
498     HasZStreamMember hasZStreamMember = {};
499     std::tie(succ, zs, hasZStreamMember) = GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
500     if (!succ) {
501         NapiBusinessError().ThrowErr(env, EINVAL);
502         return {false, {}, 0};
503     }
504 
505     // The second argument
506     NapiValue levelNVal(env, funcArg[ArgumentPosition::SECOND]);
507     int32_t level = 0;
508     std::tie(succ, level) = levelNVal.ToInt32();
509     if (!succ) {
510         NapiBusinessError().ThrowErr(env, EINVAL);
511         return {false, {}, 0};
512     }
513 
514     return {true, zs, level};
515 }
516 
GetDeflateInit2Arg(napi_env env,const NapiFuncArg & funcArg)517 std::tuple<bool, z_stream, int32_t, int32_t, int32_t, int32_t, int32_t> CommonFunc::GetDeflateInit2Arg(
518     napi_env env, const NapiFuncArg &funcArg)
519 {
520     bool succ = false;
521 
522     // The first argument
523     z_stream zs = {};
524     HasZStreamMember hasZStreamMember = {};
525     std::tie(succ, zs, hasZStreamMember) = GetZstreamArg(env, funcArg[ArgumentPosition::FIRST]);
526     if (!succ) {
527         NapiBusinessError().ThrowErr(env, EINVAL);
528         return {false, {}, 0, 0, 0, 0, 0};
529     }
530 
531     // The second argument
532     NapiValue levelNVal(env, funcArg[ArgumentPosition::SECOND]);
533     int32_t level = 0;
534     std::tie(succ, level) = levelNVal.ToInt32();
535     if (!succ) {
536         NapiBusinessError().ThrowErr(env, EINVAL);
537         return {false, {}, 0, 0, 0, 0, 0};
538     }
539 
540     // The third argument
541     NapiValue methodNVal(env, funcArg[ArgumentPosition::THIRD]);
542     int32_t method = 0;
543     std::tie(succ, method) = methodNVal.ToInt32();
544     if (!succ) {
545         NapiBusinessError().ThrowErr(env, EINVAL);
546         return {false, {}, 0, 0, 0, 0, 0};
547     }
548 
549     // The fourth argument
550     NapiValue windowBitsNVal(env, funcArg[ArgumentPosition::FOURTH]);
551     int32_t windowBits = 0;
552     std::tie(succ, windowBits) = windowBitsNVal.ToInt32();
553     if (!succ) {
554         NapiBusinessError().ThrowErr(env, EINVAL);
555         return {false, {}, 0, 0, 0, 0, 0};
556     }
557 
558     // The fifth argument
559     NapiValue memLevelNVal(env, funcArg[ArgumentPosition::FIFTH]);
560     int32_t memLevel = 0;
561     std::tie(succ, memLevel) = memLevelNVal.ToInt32();
562     if (!succ) {
563         NapiBusinessError().ThrowErr(env, EINVAL);
564         return {false, {}, 0, 0, 0, 0, 0};
565     }
566 
567     // The sixth argument
568     NapiValue strategyNVal(env, funcArg[ArgumentPosition::SIXTH]);
569     int32_t strategy = 0;
570     std::tie(succ, strategy) = strategyNVal.ToInt32();
571     if (!succ) {
572         NapiBusinessError().ThrowErr(env, EINVAL);
573         return {false, {}, 0, 0, 0, 0, 0};
574     }
575 
576     return {true, zs, level, method, windowBits, memLevel, strategy};
577 }
578 
GetDeflateArg(napi_env env,const NapiFuncArg & funcArg)579 std::tuple<bool, int32_t> CommonFunc::GetDeflateArg(napi_env env, const NapiFuncArg &funcArg)
580 {
581     // The first argument
582     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
583     if (!succ) {
584         return {false, 0};
585     }
586 
587     // The second argument
588     NapiValue flushNVal(env, funcArg[ArgumentPosition::SECOND]);
589     int32_t flush = 0;
590     std::tie(succ, flush) = flushNVal.ToInt32();
591     if (!succ) {
592         NapiBusinessError().ThrowErr(env, EINVAL);
593         return {false, 0};
594     }
595 
596     return {true, flush};
597 }
598 
GetCompressArg(napi_env env,const NapiFuncArg & funcArg)599 std::tuple<bool, void *, size_t, void *, int64_t> CommonFunc::GetCompressArg(napi_env env, const NapiFuncArg &funcArg)
600 {
601     bool succ = false;
602     void *dest = nullptr;
603     size_t destLen = 0;
604     NapiValue destNVal(env, funcArg[ArgumentPosition::FIRST]);
605     std::tie(succ, dest, destLen) = destNVal.ToArrayBuffer();
606     if (!succ) {
607         NapiBusinessError().ThrowErr(env, EINVAL);
608         return {false, nullptr, 0, nullptr, 0};
609     }
610 
611     void *source = nullptr;
612     int64_t sourceLen = 0;
613     NapiValue sourceNVal(env, funcArg[ArgumentPosition::SECOND]);
614     std::tie(succ, source, sourceLen) = sourceNVal.ToArrayBuffer();
615     if (!succ) {
616         NapiBusinessError().ThrowErr(env, EINVAL);
617         return {false, nullptr, 0, nullptr, 0};
618     }
619 
620     if (funcArg.GetArgc() == ArgumentCount::THREE) {
621         int64_t sourceLenIn = 0;
622         NapiValue sourceLenNVal(env, funcArg[ArgumentPosition::THIRD]);
623         std::tie(succ, sourceLenIn) = sourceLenNVal.ToInt64(sourceLen);
624         if (!succ || sourceLenIn < 0) {
625             NapiBusinessError().ThrowErr(env, EINVAL);
626             return { false, nullptr, 0, nullptr, 0 };
627         }
628         sourceLen = sourceLenIn;
629     }
630 
631     return {true, dest, destLen, source, sourceLen};
632 }
633 
GetCompress2Arg(napi_env env,const NapiFuncArg & funcArg)634 std::tuple<bool, void *, size_t, void *, size_t, int32_t> CommonFunc::GetCompress2Arg(
635     napi_env env, const NapiFuncArg &funcArg)
636 {
637     bool succ = false;
638     void *dest = nullptr;
639     size_t destLen = 0;
640     NapiValue destNVal(env, funcArg[ArgumentPosition::FIRST]);
641     std::tie(succ, dest, destLen) = destNVal.ToArrayBuffer();
642     if (!succ) {
643         NapiBusinessError().ThrowErr(env, EINVAL);
644         return {false, nullptr, 0, nullptr, 0, 0};
645     }
646 
647     void *source = nullptr;
648     int64_t sourceLen = 0;
649     NapiValue sourceNVal(env, funcArg[ArgumentPosition::SECOND]);
650     std::tie(succ, source, sourceLen) = sourceNVal.ToArrayBuffer();
651     if (!succ) {
652         NapiBusinessError().ThrowErr(env, EINVAL);
653         return {false, nullptr, 0, nullptr, 0, 0};
654     }
655 
656     int32_t level = 0;
657     NapiValue levelNVal(env, funcArg[ArgumentPosition::THIRD]);
658     std::tie(succ, level) = levelNVal.ToInt32();
659     if (!succ) {
660         NapiBusinessError().ThrowErr(env, EINVAL);
661         return {false, nullptr, 0, nullptr, 0, 0};
662     }
663 
664     if (funcArg.GetArgc() == ArgumentCount::FOUR) {
665         int64_t sourceLenIn = 0;
666         NapiValue sourceLenNVal(env, funcArg[ArgumentPosition::FOURTH]);
667         std::tie(succ, sourceLenIn) = sourceLenNVal.ToInt64(sourceLen);
668         if (!succ || sourceLenIn < 0) {
669             NapiBusinessError().ThrowErr(env, EINVAL);
670             return {false, nullptr, 0, nullptr, 0, 0};
671         }
672         sourceLen = sourceLenIn;
673     }
674 
675     return {true, dest, destLen, source, sourceLen, level};
676 }
677 
GetUnCompressArg(napi_env env,const NapiFuncArg & funcArg)678 std::tuple<bool, void *, size_t, void *, int64_t> CommonFunc::GetUnCompressArg(napi_env env, const NapiFuncArg &funcArg)
679 {
680     bool succ = false;
681     void *dest = nullptr;
682     size_t destLen = 0;
683     NapiValue destNVal(env, funcArg[ArgumentPosition::FIRST]);
684     std::tie(succ, dest, destLen) = destNVal.ToArrayBuffer();
685     if (!succ) {
686         NapiBusinessError().ThrowErr(env, EINVAL);
687         return {false, nullptr, 0, nullptr, 0};
688     }
689 
690     void *source = nullptr;
691     int64_t sourceLen = 0;
692     NapiValue sourceNVal(env, funcArg[ArgumentPosition::SECOND]);
693     std::tie(succ, source, sourceLen) = sourceNVal.ToArrayBuffer();
694     if (!succ) {
695         NapiBusinessError().ThrowErr(env, EINVAL);
696         return {false, nullptr, 0, nullptr, 0};
697     }
698 
699     if (funcArg.GetArgc() == ArgumentCount::THREE) {
700         int64_t sourceLenIn = 0;
701         NapiValue sourceLenNVal(env, funcArg[ArgumentPosition::THIRD]);
702         std::tie(succ, sourceLenIn) = sourceLenNVal.ToInt64(sourceLen);
703         if (!succ || sourceLenIn < 0) {
704             NapiBusinessError().ThrowErr(env, EINVAL);
705             return { false, nullptr, 0, nullptr, 0 };
706         }
707         sourceLen = sourceLenIn;
708     }
709 
710     return {true, dest, destLen, source, sourceLen};
711 }
712 
GetZErrorArg(napi_env env,const NapiFuncArg & funcArg)713 std::tuple<bool, int32_t> CommonFunc::GetZErrorArg(napi_env env, const NapiFuncArg &funcArg)
714 {
715     bool succ = false;
716     NapiValue errNVal(env, funcArg[ArgumentPosition::FIRST]);
717     int32_t zlibError = 0;
718     std::tie(succ, zlibError) = errNVal.ToInt32();
719     if (!succ) {
720         NapiBusinessError().ThrowErr(env, EINVAL);
721         return {false, 0};
722     }
723 
724     return {true, zlibError};
725 }
726 
GetInflateSetDictionaryArg(napi_env env,const NapiFuncArg & funcArg)727 std::tuple<bool, void *, size_t> CommonFunc::GetInflateSetDictionaryArg(napi_env env, const NapiFuncArg &funcArg)
728 {
729     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
730     if (!succ) {
731         NapiBusinessError().ThrowErr(env, EINVAL);
732         return {false, nullptr, 0};
733     }
734 
735     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
736     void *buf = nullptr;
737     size_t bufLen = 0;
738     std::tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
739     if (!succ) {
740         NapiBusinessError().ThrowErr(env, EINVAL);
741         return {false, nullptr, 0};
742     }
743 
744     return {true, buf, bufLen};
745 }
746 
GetInflateArg(napi_env env,const NapiFuncArg & funcArg)747 std::tuple<bool, int32_t> CommonFunc::GetInflateArg(napi_env env, const NapiFuncArg &funcArg)
748 {
749     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
750     if (!succ) {
751         NapiBusinessError().ThrowErr(env, EINVAL);
752         return {false, 0};
753     }
754 
755     NapiValue flushNVal(env, funcArg[ArgumentPosition::SECOND]);
756     int32_t flush = 0;
757     std::tie(succ, flush) = flushNVal.ToInt32();
758     if (!succ) {
759         NapiBusinessError().ThrowErr(env, EINVAL);
760         return {false, 0};
761     }
762 
763     return {true, flush};
764 }
765 
GetInflateReset2Arg(napi_env env,const NapiFuncArg & funcArg)766 std::tuple<bool, int32_t> CommonFunc::GetInflateReset2Arg(napi_env env, const NapiFuncArg &funcArg)
767 {
768     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
769     if (!succ) {
770         NapiBusinessError().ThrowErr(env, EINVAL);
771         return {false, 0};
772     }
773 
774     NapiValue flushNVal(env, funcArg[ArgumentPosition::SECOND]);
775     int32_t flush = 0;
776     std::tie(succ, flush) = flushNVal.ToInt32();
777     if (!succ) {
778         NapiBusinessError().ThrowErr(env, EINVAL);
779         return {false, 0};
780     }
781 
782     return {true, flush};
783 }
784 
GetInflateBackInitArg(napi_env env,const NapiFuncArg & funcArg)785 std::tuple<bool, unsigned long, void*, size_t> CommonFunc::GetInflateBackInitArg(
786     napi_env env, const NapiFuncArg& funcArg)
787 {
788     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
789     if (!succ) {
790         NapiBusinessError().ThrowErr(env, EINVAL);
791         return {false, 0, nullptr, 0};
792     }
793 
794     int32_t windowBits = 0;
795     NapiValue windowBitsNVal(env, funcArg[ArgumentPosition::SECOND]);
796     std::tie(succ, windowBits) = windowBitsNVal.ToInt64();
797     if (!succ || windowBits < MIN_WINDOWBITS || windowBits > MAX_WINDOWBITS) {
798         NapiBusinessError().ThrowErr(env, EINVAL);
799         return {false, 0, nullptr, 0};
800     }
801 
802     NapiValue bufNVal(env, funcArg[ArgumentPosition::THIRD]);
803     void *buf = nullptr;
804     size_t bufLen = 0;
805     std::tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
806     if (!succ) {
807         NapiBusinessError().ThrowErr(env, EINVAL);
808         return {false, 0, nullptr, 0};
809     }
810 
811     return {true, windowBits, buf, bufLen};
812 }
813 
GetInflatePrimeArg(napi_env env,const NapiFuncArg & funcArg)814 std::tuple<bool, int32_t, int32_t> CommonFunc::GetInflatePrimeArg(napi_env env, const NapiFuncArg &funcArg)
815 {
816     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
817     if (!succ) {
818         NapiBusinessError().ThrowErr(env, EINVAL);
819         return {false, 0, 0};
820     }
821 
822     NapiValue bitsNVal(env, funcArg[ArgumentPosition::SECOND]);
823     int32_t bits = 0;
824     std::tie(succ, bits) = bitsNVal.ToInt32();
825     if (!succ) {
826         NapiBusinessError().ThrowErr(env, EINVAL);
827         return {false, 0, 0};
828     }
829 
830     // The third argument
831     NapiValue valueNVal(env, funcArg[ArgumentPosition::THIRD]);
832     int32_t value = 0;
833     std::tie(succ, value) = valueNVal.ToInt32();
834     if (!succ) {
835         NapiBusinessError().ThrowErr(env, EINVAL);
836         return {false, 0, 0};
837     }
838     return {true, bits, value};
839 }
840 
GetInflateValidateArg(napi_env env,const NapiFuncArg & funcArg)841 std::tuple<bool, int32_t> CommonFunc::GetInflateValidateArg(napi_env env, const NapiFuncArg &funcArg)
842 {
843     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
844     if (!succ) {
845         NapiBusinessError().ThrowErr(env, EINVAL);
846         return {false, 0};
847     }
848 
849     NapiValue checkNVal(env, funcArg[ArgumentPosition::SECOND]);
850     int32_t check = 0;
851     std::tie(succ, check) = checkNVal.ToInt32();
852     if (!succ) {
853         NapiBusinessError().ThrowErr(env, EINVAL);
854         return {false, 0};
855     }
856 
857     return {true, check};
858 }
859 
GetInflateGetHeaderArg(napi_env env,const NapiFuncArg & funcArg)860 std::tuple<bool, gz_header> CommonFunc::GetInflateGetHeaderArg(napi_env env, const NapiFuncArg &funcArg)
861 {
862     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
863     if (!succ) {
864         NapiBusinessError().ThrowErr(env, EINVAL);
865         return {false, {}};
866     }
867 
868     gz_header gzHeader = {};
869     std::tie(succ, gzHeader) = CommonFunc::GetGZHeaderArg(env, funcArg[ArgumentPosition::SECOND]);
870     if (!succ) {
871         return {false, {}};
872     }
873 
874     return {true, gzHeader};
875 }
876 
UnwrapInt32Params(napi_env env,napi_value value)877 std::tuple<bool, int32_t> CommonFunc::UnwrapInt32Params(napi_env env, napi_value value)
878 {
879     bool succ = false;
880 
881     // The first argument
882     NapiValue valueNVal(env, value);
883     int32_t valueInt = 0;
884     std::tie(succ, valueInt) = valueNVal.ToInt32();
885     if (!succ || valueInt < 0) {
886         NapiBusinessError().ThrowErr(env, EINVAL);
887         return {false, 0};
888     }
889 
890     return {true, valueInt};
891 }
892 
UnwrapInt64Params(napi_env env,const NapiFuncArg & funcArg)893 std::tuple<bool, uint32_t> CommonFunc::UnwrapInt64Params(napi_env env, const NapiFuncArg &funcArg)
894 {
895     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
896     if (!succ) {
897         NapiBusinessError().ThrowErr(env, EINVAL);
898         return {false, {}};
899     }
900 
901     // The first argument
902     NapiValue valueNVal(env, funcArg[ArgumentPosition::SECOND]);
903     int64_t valueInt = 0;
904     std::tie(succ, valueInt) = valueNVal.ToInt64();
905     if (!succ || valueInt < 0) {
906         NapiBusinessError().ThrowErr(env, EINVAL);
907         return {false, 0};
908     }
909 
910     return {true, valueInt};
911 }
912 
UnwrapDeflateTuneParams(napi_env env,const NapiFuncArg & funcArg)913 std::tuple<bool, int32_t, int32_t, int32_t, int32_t> CommonFunc::UnwrapDeflateTuneParams(
914     napi_env env, const NapiFuncArg &funcArg)
915 {
916     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
917     if (!succ) {
918         return {false, 0, 0, 0, 0};
919     }
920 
921     // The first argument
922     NapiValue goodLengthNVal(env, funcArg[ArgumentPosition::SECOND]);
923     int32_t goodLength = 0;
924     std::tie(succ, goodLength) = goodLengthNVal.ToInt32();
925     if (!succ) {
926         NapiBusinessError().ThrowErr(env, EINVAL);
927         return {false, 0, 0, 0, 0};
928     }
929 
930     NapiValue maxLazyNVal(env, funcArg[ArgumentPosition::THIRD]);
931     int32_t maxLazy = 0;
932     std::tie(succ, maxLazy) = maxLazyNVal.ToInt32();
933     if (!succ) {
934         NapiBusinessError().ThrowErr(env, EINVAL);
935         return {false, 0, 0, 0, 0};
936     }
937 
938     NapiValue niceLengthNVal(env, funcArg[ArgumentPosition::FOURTH]);
939     int32_t niceLength = 0;
940     std::tie(succ, niceLength) = niceLengthNVal.ToInt32();
941     if (!succ) {
942         NapiBusinessError().ThrowErr(env, EINVAL);
943         return {false, 0, 0, 0, 0};
944     }
945 
946     NapiValue maxChainNVal(env, funcArg[ArgumentPosition::FIFTH]);
947     int32_t maxChain = 0;
948     std::tie(succ, maxChain) = maxChainNVal.ToInt32();
949     if (!succ) {
950         NapiBusinessError().ThrowErr(env, EINVAL);
951         return {false, 0, 0, 0, 0};
952     }
953 
954     return {true, maxLazy, maxLazy, niceLength, maxChain};
955 }
956 
UnwrapArrayBufferParams(napi_env env,const NapiFuncArg & funcArg)957 std::tuple<bool, void *, size_t> CommonFunc::UnwrapArrayBufferParams(napi_env env, const NapiFuncArg &funcArg)
958 {
959     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
960     if (!succ) {
961         return {false, nullptr, 0};
962     }
963 
964     NapiValue bufNVal(env, funcArg[ArgumentPosition::SECOND]);
965     void *buf = nullptr;
966     size_t bufLen = 0;
967     std::tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
968     if (!succ) {
969         NapiBusinessError().ThrowErr(env, EINVAL);
970         return {false, nullptr, 0};
971     }
972 
973     return {true, buf, bufLen};
974 }
975 
UnwrapTwoIntParams(napi_env env,const NapiFuncArg & funcArg)976 std::tuple<bool, int32_t, int32_t> CommonFunc::UnwrapTwoIntParams(napi_env env, const NapiFuncArg &funcArg)
977 {
978     bool succ = CommonFunc::SetZStreamValue(env, funcArg);
979     if (!succ) {
980         return {false, 0, 0};
981     }
982 
983     // The first argument
984     NapiValue firstNVal(env, funcArg[ArgumentPosition::SECOND]);
985     int32_t oneInt = 0;
986     std::tie(succ, oneInt) = firstNVal.ToInt32();
987     if (!succ) {
988         NapiBusinessError().ThrowErr(env, EINVAL);
989         return {false, 0, 0};
990     }
991 
992     // The second argument
993     NapiValue secondNVal(env, funcArg[ArgumentPosition::THIRD]);
994     int32_t twoInt = 0;
995     std::tie(succ, twoInt) = secondNVal.ToInt32();
996     if (!succ) {
997         NapiBusinessError().ThrowErr(env, EINVAL);
998         return {false, 0, 0};
999     }
1000 
1001     return {true, oneInt, twoInt};
1002 }
1003 
GzipUnwrapArrayBufferParams(napi_env env,const NapiFuncArg & funcArg)1004 std::tuple<bool, void *, size_t> CommonFunc::GzipUnwrapArrayBufferParams(napi_env env, const NapiFuncArg &funcArg)
1005 {
1006     bool succ = false;
1007     void *buf = nullptr;
1008     size_t bufLen = 0;
1009     NapiValue bufNVal(env, funcArg[ArgumentPosition::FIRST]);
1010     std::tie(succ, buf, bufLen) = bufNVal.ToArrayBuffer();
1011     if (!succ) {
1012         NapiBusinessError().ThrowErr(env, EINVAL);
1013         return {false, nullptr, 0};
1014     }
1015 
1016     return {true, buf, bufLen};
1017 }
1018 
GetGZOpenArg(napi_env env,const NapiFuncArg & funcArg)1019 std::tuple<bool, std::unique_ptr<char[]>, std::unique_ptr<char[]>> CommonFunc::GetGZOpenArg(
1020     napi_env env, const NapiFuncArg &funcArg)
1021 {
1022     bool succ = false;
1023     std::unique_ptr<char[]> path = nullptr;
1024     size_t bufferLen = 0;
1025     NapiValue pathNVal(env, funcArg[ArgumentPosition::FIRST]);
1026     std::tie(succ, path, bufferLen) = pathNVal.ToUTF8String();
1027     if (!succ) {
1028         NapiBusinessError().ThrowErr(env, EINVAL);
1029         return {false, nullptr, nullptr};
1030     }
1031 
1032     std::unique_ptr<char[]> mode = nullptr;
1033     bufferLen = 0;
1034     NapiValue modeNVal(env, funcArg[ArgumentPosition::SECOND]);
1035     std::tie(succ, mode, bufferLen) = modeNVal.ToUTF8String();
1036     if (!succ) {
1037         NapiBusinessError().ThrowErr(env, EINVAL);
1038         return {false, nullptr, nullptr};
1039     }
1040     return {true, std::move(path), std::move(mode)};
1041 }
1042 
GetGZDOpenArg(napi_env env,const NapiFuncArg & funcArg)1043 std::tuple<bool, int32_t, std::unique_ptr<char[]>> CommonFunc::GetGZDOpenArg(napi_env env, const NapiFuncArg &funcArg)
1044 {
1045     bool succ = false;
1046     int32_t fd = -1;
1047     NapiValue fdNVal(env, funcArg[ArgumentPosition::FIRST]);
1048     std::tie(succ, fd) = fdNVal.ToInt32();
1049     if (!succ) {
1050         NapiBusinessError().ThrowErr(env, EINVAL);
1051         return {false, -1, nullptr};
1052     }
1053 
1054     std::unique_ptr<char[]> mode = nullptr;
1055     size_t bufferLen = 0;
1056     NapiValue modeNVal(env, funcArg[ArgumentPosition::SECOND]);
1057     std::tie(succ, mode, bufferLen) = modeNVal.ToUTF8String();
1058     if (!succ) {
1059         NapiBusinessError().ThrowErr(env, EINVAL);
1060         return {false, -1, nullptr};
1061     }
1062     return {true, fd, std::move(mode)};
1063 }
1064 
GetGZFileArg(napi_env env,napi_value argGZFile)1065 std::tuple<bool, gzFile_s, HasGZFileMember> CommonFunc::GetGZFileArg(napi_env env, napi_value argGZFile)
1066 {
1067     gzFile_s gzs = {};
1068     bool succ = false;
1069     NapiValue gzFileNVal(env, argGZFile);
1070     HasGZFileMember hasGZFileMember = {};
1071 
1072     if (gzFileNVal.HasProp("have") && !gzFileNVal.GetProp("have").TypeIs(napi_undefined)) {
1073         uint32_t have = 0;
1074         std::tie(succ, have) = gzFileNVal.GetProp("have").ToUint32();
1075         if (!succ) {
1076             NapiBusinessError().ThrowErr(env, EINVAL);
1077             return {false, {}, {}};
1078         }
1079         gzs.have = have;
1080         hasGZFileMember.hasHave = true;
1081     }
1082 
1083     if (gzFileNVal.HasProp("next") && !gzFileNVal.GetProp("next").TypeIs(napi_undefined)) {
1084         void *buf = nullptr;
1085         size_t bufLen = 0;
1086         std::tie(succ, buf, bufLen) = gzFileNVal.GetProp("next").ToArrayBuffer();
1087         if (!succ) {
1088             NapiBusinessError().ThrowErr(env, EINVAL);
1089             return {false, {}, {}};
1090         }
1091         gzs.next = reinterpret_cast<Bytef *>(buf);
1092         hasGZFileMember.hasNext = true;
1093     }
1094 
1095     if (gzFileNVal.HasProp("pos") && !gzFileNVal.GetProp("pos").TypeIs(napi_undefined)) {
1096         uint64_t pos = 0U;
1097         std::tie(succ, pos) = gzFileNVal.GetProp("pos").ToInt64();
1098         if (!succ) {
1099             NapiBusinessError().ThrowErr(env, EINVAL);
1100             return {false, {}, {}};
1101         }
1102         gzs.pos = static_cast<z_off64_t>(pos);
1103         hasGZFileMember.hasPos = true;
1104     }
1105     return {true, gzs, hasGZFileMember};
1106 }
1107 
GetGZBufferArg(napi_env env,const NapiFuncArg & funcArg)1108 std::tuple<bool, uint32_t> CommonFunc::GetGZBufferArg(napi_env env, const NapiFuncArg &funcArg)
1109 {
1110     bool succ = false;
1111     uint32_t size = 0;
1112     NapiValue sizeNVal(env, funcArg[ArgumentPosition::FIRST]);
1113     std::tie(succ, size) = sizeNVal.ToUint32();
1114     if (!succ) {
1115         NapiBusinessError().ThrowErr(env, EINVAL);
1116         return {false, 0};
1117     }
1118     return {true, size};
1119 }
1120 
GetGZReadArg(napi_env env,const NapiFuncArg & funcArg)1121 std::tuple<bool, void *, uint32_t> CommonFunc::GetGZReadArg(napi_env env, const NapiFuncArg &funcArg)
1122 {
1123     bool succ = false;
1124     void *buf = nullptr;
1125     size_t len = 0;
1126     std::tie(succ, buf, len) = GzipUnwrapArrayBufferParams(env, funcArg);
1127     if (!succ || len == 0) {
1128         NapiBusinessError().ThrowErr(env, EINVAL);
1129         return {false, nullptr, 0};
1130     }
1131     return {true, buf, len};
1132 }
1133 
GetGZFReadArg(napi_env env,const NapiFuncArg & funcArg)1134 std::tuple<bool, void *, int64_t, int64_t> CommonFunc::GetGZFReadArg(napi_env env, const NapiFuncArg &funcArg)
1135 {
1136     bool succ = false;
1137     void *buf = nullptr;
1138     size_t len = 0;
1139     std::tie(succ, buf, len) = GzipUnwrapArrayBufferParams(env, funcArg);
1140     if (!succ || len == 0) {
1141         NapiBusinessError().ThrowErr(env, EINVAL);
1142         return {false, nullptr, 0, 0};
1143     }
1144 
1145     int64_t size = 0;
1146     NapiValue sizeNVal(env, funcArg[ArgumentPosition::SECOND]);
1147     std::tie(succ, size) = sizeNVal.ToInt64();
1148     if (!succ || size < 0) {
1149         NapiBusinessError().ThrowErr(env, EINVAL);
1150         return {false, nullptr, 0, 0};
1151     }
1152 
1153     int64_t nitems = 0;
1154     NapiValue nitemsNVal(env, funcArg[ArgumentPosition::THIRD]);
1155     std::tie(succ, nitems) = nitemsNVal.ToInt64();
1156     if (!succ || nitems < 0) {
1157         NapiBusinessError().ThrowErr(env, EINVAL);
1158         return {false, nullptr, 0, 0};
1159     }
1160     if (nitems != 0 && (size > (static_cast<int64_t>(len) / nitems))) {
1161         APP_LOGE("buf too small");
1162         NapiBusinessError().ThrowErr(env, EINVAL);
1163         return {false, nullptr, 0, 0};
1164     }
1165     return {true, buf, size, nitems};
1166 }
1167 
GetGZWriteArg(napi_env env,const NapiFuncArg & funcArg)1168 std::tuple<bool, void *, int64_t> CommonFunc::GetGZWriteArg(napi_env env, const NapiFuncArg &funcArg)
1169 {
1170     bool succ = false;
1171     void *buf = nullptr;
1172     size_t bufLen = 0;
1173     std::tie(succ, buf, bufLen) = GzipUnwrapArrayBufferParams(env, funcArg);
1174     if (!succ || bufLen == 0) {
1175         NapiBusinessError().ThrowErr(env, EINVAL);
1176         return {false, nullptr, 0};
1177     }
1178     int64_t len = 0;
1179     NapiValue sizeNVal(env, funcArg[ArgumentPosition::SECOND]);
1180     std::tie(succ, len) = sizeNVal.ToInt64();
1181     if (!succ || len > static_cast<int64_t>(bufLen)) {
1182         NapiBusinessError().ThrowErr(env, EINVAL);
1183         return {false, nullptr, 0};
1184     }
1185     return {true, buf, len};
1186 }
1187 
GetGZFWriteArg(napi_env env,const NapiFuncArg & funcArg)1188 std::tuple<bool, void *, int64_t, int64_t> CommonFunc::GetGZFWriteArg(napi_env env, const NapiFuncArg &funcArg)
1189 {
1190     bool succ = false;
1191     void *buf = nullptr;
1192     size_t len = 0;
1193     std::tie(succ, buf, len) = GzipUnwrapArrayBufferParams(env, funcArg);
1194     if (!succ || len == 0) {
1195         NapiBusinessError().ThrowErr(env, EINVAL);
1196         return {false, nullptr, 0, 0};
1197     }
1198 
1199     int64_t size = 0;
1200     NapiValue sizeNVal(env, funcArg[ArgumentPosition::SECOND]);
1201     std::tie(succ, size) = sizeNVal.ToInt64();
1202     if (!succ || size < 0) {
1203         NapiBusinessError().ThrowErr(env, EINVAL);
1204         return {false, nullptr, 0, 0};
1205     }
1206 
1207     int64_t nitems = 0;
1208     NapiValue nitemsNVal(env, funcArg[ArgumentPosition::THIRD]);
1209     std::tie(succ, nitems) = nitemsNVal.ToInt64();
1210     if (!succ || nitems < 0) {
1211         NapiBusinessError().ThrowErr(env, EINVAL);
1212         return {false, nullptr, 0, 0};
1213     }
1214     if (nitems != 0 && (size > (static_cast<int64_t>(len) / nitems))) {
1215         APP_LOGE("buf too small");
1216         NapiBusinessError().ThrowErr(env, EINVAL);
1217         return {false, nullptr, 0, 0};
1218     }
1219     return {true, buf, size, nitems};
1220 }
1221 
GetGZPutCArg(napi_env env,const NapiFuncArg & funcArg)1222 std::tuple<bool, int32_t> CommonFunc::GetGZPutCArg(napi_env env, const NapiFuncArg &funcArg)
1223 {
1224     bool succ = false;
1225     int32_t c = 0;
1226     NapiValue cNVal(env, funcArg[ArgumentPosition::FIRST]);
1227     std::tie(succ, c) = cNVal.ToInt32();
1228     if (!succ) {
1229         NapiBusinessError().ThrowErr(env, EINVAL);
1230         return {false, 0};
1231     }
1232     if (c < MIN_ASCII || c > MAX_ASCII) {
1233         NapiBusinessError().ThrowErr(env, EINVAL);
1234         return {false, 0};
1235     }
1236     return {true, c};
1237 }
1238 
GetGZPutSArg(napi_env env,const NapiFuncArg & funcArg)1239 std::tuple<bool, std::unique_ptr<char[]>> CommonFunc::GetGZPutSArg(napi_env env, const NapiFuncArg &funcArg)
1240 {
1241     bool succ = false;
1242     std::unique_ptr<char[]> s = nullptr;
1243     size_t len = 0;
1244     NapiValue sNVal(env, funcArg[ArgumentPosition::FIRST]);
1245     std::tie(succ, s, len) = sNVal.ToUTF8String();
1246     if (!succ) {
1247         NapiBusinessError().ThrowErr(env, EINVAL);
1248         return {false, nullptr};
1249     }
1250     return {true, std::move(s)};
1251 }
1252 
GetGzSetParamsArg(napi_env env,const NapiFuncArg & funcArg)1253 std::tuple<bool, int32_t, int32_t> CommonFunc::GetGzSetParamsArg(napi_env env, const NapiFuncArg &funcArg)
1254 {
1255     bool succ = false;
1256     int32_t level = 0;
1257     NapiValue levelNapiValue(env, funcArg[ArgumentPosition::FIRST]);
1258     std::tie(succ, level) = levelNapiValue.ToInt32();
1259     if (!succ) {
1260         NapiBusinessError().ThrowErr(env, EINVAL);
1261         return {false, -1, -1};
1262     }
1263 
1264     int32_t strategy = 0;
1265     NapiValue strategyNapiValue(env, funcArg[ArgumentPosition::SECOND]);
1266     std::tie(succ, strategy) = strategyNapiValue.ToInt32();
1267     if (!succ) {
1268         NapiBusinessError().ThrowErr(env, EINVAL);
1269         return {false, -1, -1};
1270     }
1271     return {true, level, strategy};
1272 }
1273 
GetLogContent(std::string & formatStr,const std::vector<NapiParam> & params,std::string & ret,uint32_t & pos)1274 void CommonFunc::GetLogContent(std::string &formatStr,
1275     const std::vector<NapiParam> &params, std::string &ret, uint32_t &pos)
1276 {
1277     uint32_t count = 0;
1278     for (; pos < formatStr.size(); ++pos) {
1279         if (count >= params.size()) {
1280             break;
1281         }
1282         if (formatStr[pos] != '%') {
1283             ret += formatStr[pos];
1284             continue;
1285         }
1286         if (pos + 1 >= formatStr.size()) {
1287             break;
1288         }
1289         switch (formatStr[pos + 1]) {
1290             case 'd':
1291             case 'i':
1292                 if (params[count].type == napi_number || params[count].type == napi_bigint) {
1293                     ret += params[count].val;
1294                 }
1295                 count++;
1296                 ++pos;
1297                 break;
1298             case 's':
1299                 if (params[count].type == napi_string || params[count].type == napi_undefined ||
1300                     params[count].type == napi_boolean || params[count].type == napi_null) {
1301                     ret += params[count].val;
1302                 }
1303                 count++;
1304                 ++pos;
1305                 break;
1306             case 'O':
1307             case 'o':
1308                 if (params[count].type == napi_object) {
1309                     ret += params[count].val;
1310                 }
1311                 count++;
1312                 ++pos;
1313                 break;
1314             case '%':
1315                 ret += formatStr[pos];
1316                 ++pos;
1317                 break;
1318             default:
1319                 ret += formatStr[pos];
1320                 break;
1321         }
1322     }
1323     return;
1324 }
1325 
ParseLogContent(std::string & formatStr,std::vector<NapiParam> & params,std::string & logContent)1326 void CommonFunc::ParseLogContent(std::string &formatStr, std::vector<NapiParam> &params, std::string &logContent)
1327 {
1328     std::string &ret = logContent;
1329     if (params.empty()) {
1330         ret += formatStr;
1331         return;
1332     }
1333     auto len = formatStr.size();
1334     uint32_t pos = 0;
1335     GetLogContent(formatStr, params, ret, pos);
1336     if (pos < len) {
1337         ret += formatStr.substr(pos, len - pos);
1338     }
1339     return;
1340 }
1341 
ParseNapiValue(napi_env env,napi_value element,std::vector<NapiParam> & params)1342 void CommonFunc::ParseNapiValue(napi_env env, napi_value element, std::vector<NapiParam> &params)
1343 {
1344     bool succ = false;
1345     napi_valuetype type;
1346     NapiParam res = {napi_null, ""};
1347     napi_status typeStatus = napi_typeof(env, element, &type);
1348     std::unique_ptr<char[]> name;
1349     size_t len = 0;
1350     if (typeStatus != napi_ok) {
1351         NapiBusinessError().ThrowErr(env, EINVAL);
1352         return;
1353     }
1354     if (type == napi_number || type == napi_bigint || type == napi_object || type == napi_undefined ||
1355         type == napi_boolean || type == napi_null) {
1356         napi_value elmString;
1357         napi_status objectStatus = napi_coerce_to_string(env, element, &elmString);
1358         if (objectStatus != napi_ok) {
1359             NapiBusinessError().ThrowErr(env, EINVAL);
1360             return;
1361         }
1362         NapiValue elmNVal(env, elmString);
1363         std::tie(succ, name, len) = elmNVal.ToUTF8String();
1364         if (!succ) {
1365             NapiBusinessError().ThrowErr(env, EINVAL);
1366             return;
1367         }
1368     } else if (type == napi_string) {
1369         NapiValue elmNVal(env, element);
1370         std::tie(succ, name, len) = elmNVal.ToUTF8String();
1371         if (!succ) {
1372             NapiBusinessError().ThrowErr(env, EINVAL);
1373             return;
1374         }
1375     } else {
1376         NapiBusinessError().ThrowErr(env, EINVAL);
1377     }
1378     res.type = type;
1379     if (name != nullptr) {
1380         res.val = name.get();
1381     }
1382     params.emplace_back(res);
1383     return;
1384 }
1385 
ParseNapiValueFromArray(napi_env env,std::vector<NapiParam> & params,const NapiFuncArg & funcArg)1386 bool CommonFunc::ParseNapiValueFromArray(napi_env env, std::vector<NapiParam> &params, const NapiFuncArg &funcArg)
1387 {
1388     napi_value array = funcArg[ArgumentPosition::SECOND];
1389     if (funcArg.GetArgc() != MIN_NUMBER + 1) {
1390         NapiBusinessError().ThrowErr(env, EINVAL);
1391         return false;
1392     }
1393     uint32_t length;
1394     napi_status lengthStatus = napi_get_array_length(env, array, &length);
1395     if (lengthStatus != napi_ok) {
1396         return false;
1397     }
1398     uint32_t i;
1399     for (i = 0; i < length; i++) {
1400         napi_value element;
1401         napi_status eleStatus = napi_get_element(env, array, i, &element);
1402         if (eleStatus != napi_ok) {
1403             return false;
1404         }
1405         ParseNapiValue(env, element, params);
1406     }
1407     return true;
1408 }
1409 
GetGZPrintFArg(napi_env env,const NapiFuncArg & funcArg)1410 std::tuple<bool, std::unique_ptr<char[]>, std::unique_ptr<char[]>> CommonFunc::GetGZPrintFArg(
1411     napi_env env, const NapiFuncArg &funcArg)
1412 {
1413     bool succ = false;
1414     std::unique_ptr<char[]> fmtChar = nullptr;
1415     size_t len = 0;
1416     NapiValue formatNapiValue(env, funcArg[ArgumentPosition::FIRST]);
1417     std::tie(succ, fmtChar, len) = formatNapiValue.ToUTF8String();
1418     if (!succ) {
1419         NapiBusinessError().ThrowErr(env, EINVAL);
1420         return {false, nullptr, nullptr};
1421     }
1422     std::string fmtString = fmtChar.get();
1423 
1424     bool res = false;
1425     napi_value array = funcArg[ArgumentPosition::SECOND];
1426     napi_is_array(env, array, &res);
1427     std::string printContent;
1428     std::vector<NapiParam> params;
1429     if (!res) {
1430         for (size_t i = MIN_NUMBER; i < funcArg.GetArgc(); i++) {
1431             napi_value argsVal = funcArg[i];
1432             ParseNapiValue(env, argsVal, params);
1433         }
1434     } else {
1435         bool isSuccess = ParseNapiValueFromArray(env, params, funcArg);
1436         if (!isSuccess) {
1437             return {false, nullptr, nullptr};
1438         }
1439     }
1440     ParseLogContent(fmtString, params, printContent);
1441 
1442     std::unique_ptr<char[]> formatChar = nullptr;
1443     NapiValue formatNVal = NapiValue::CreateUTF8String(env, "%s");
1444     std::tie(succ, formatChar, len) = formatNVal.ToUTF8String();
1445     std::unique_ptr<char[]> argsChar = nullptr;
1446     NapiValue printNVal = NapiValue::CreateUTF8String(env, printContent);
1447     std::tie(succ, argsChar, len) = printNVal.ToUTF8String();
1448     return {true, std::move(formatChar), std::move(argsChar)};
1449 }
1450 
GetGZGetSArg(napi_env env,const NapiFuncArg & funcArg)1451 std::tuple<bool, void *, size_t> CommonFunc::GetGZGetSArg(napi_env env, const NapiFuncArg &funcArg)
1452 {
1453     bool succ = false;
1454     void *buffer = nullptr;
1455     size_t bufferLen = 0;
1456     NapiValue bufferNVal(env, funcArg[ArgumentPosition::FIRST]);
1457     std::tie(succ, buffer, bufferLen) = bufferNVal.ToArrayBuffer();
1458     if (!succ) {
1459         NapiBusinessError().ThrowErr(env, EINVAL);
1460         return {false, nullptr, 0};
1461     }
1462     return {true, buffer, bufferLen};
1463 }
1464 
GetGZSeekArg(napi_env env,const NapiFuncArg & funcArg)1465 std::tuple<bool, int64_t, int32_t> CommonFunc::GetGZSeekArg(napi_env env, const NapiFuncArg &funcArg)
1466 {
1467     bool succ = false;
1468     int64_t offset = 0;
1469     NapiValue offsetNVal(env, funcArg[ArgumentPosition::FIRST]);
1470     std::tie(succ, offset) = offsetNVal.ToInt64();
1471     if (!succ) {
1472         NapiBusinessError().ThrowErr(env, EINVAL);
1473         return {false, 0, 0};
1474     }
1475 
1476     int32_t whence = 0;
1477     NapiValue whenceNVal(env, funcArg[ArgumentPosition::SECOND]);
1478     std::tie(succ, whence) = whenceNVal.ToInt32();
1479     if (!succ) {
1480         NapiBusinessError().ThrowErr(env, EINVAL);
1481         return {false, 0, 0};
1482     }
1483     return {true, offset, whence};
1484 }
1485 
GetGZUnGetCArg(napi_env env,const NapiFuncArg & funcArg)1486 std::tuple<bool, int32_t> CommonFunc::GetGZUnGetCArg(napi_env env, const NapiFuncArg &funcArg)
1487 {
1488     bool succ = false;
1489     int32_t c = 0;
1490     NapiValue cNVal(env, funcArg[ArgumentPosition::FIRST]);
1491     std::tie(succ, c) = cNVal.ToInt32();
1492     if (!succ) {
1493         NapiBusinessError().ThrowErr(env, EINVAL);
1494         return {false, 0};
1495     }
1496     if (c < MIN_ASCII || c > MAX_ASCII) {
1497         NapiBusinessError().ThrowErr(env, EINVAL);
1498         return {false, 0};
1499     }
1500     return {true, c};
1501 }
1502 
SetGZFlushArg(napi_env env,const NapiFuncArg & funcArg)1503 std::tuple<bool, uint32_t> CommonFunc::SetGZFlushArg(napi_env env, const NapiFuncArg &funcArg)
1504 {
1505     bool succ = false;
1506     uint32_t flush = 0;
1507     NapiValue sizeNVal(env, funcArg[ArgumentPosition::FIRST]);
1508     std::tie(succ, flush) = sizeNVal.ToUint32();
1509     if (!succ) {
1510         NapiBusinessError().ThrowErr(env, EINVAL);
1511         return {false, 0};
1512     }
1513     return {true, flush};
1514 }
1515 
1516 }  // namespace LIBZIP
1517 }  // namespace AppExecFwk
1518 }  // namespace OHOS