• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "js_base64.h"
17 #include <cstring>
18 #include <sys/types.h>
19 #include "utils/log.h"
20 #include "securec.h"
21 #include "napi/native_api.h"
22 #include "napi/native_node_api.h"
23 
24 namespace OHOS::Util {
25     namespace {
26         static const size_t TRAGET_TWO = 2;
27         static const size_t TRAGET_THREE = 3;
28         static const size_t TRAGET_FOUR = 4;
29         static const size_t TRAGET_SIX = 6;
30         static const size_t TRAGET_EIGHT = 8;
31         static const size_t TRAGET_SIXTYFIVE = 65;
32         const char BASE[] = {
33             65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82,
34             83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105,
35             106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120,
36             121, 122, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 43, 47, 61
37         };
38     }
39 
40     /* base64 encode */
EncodeSync(napi_env env,napi_value src)41     napi_value Base64::EncodeSync(napi_env env, napi_value src)
42     {
43         napi_typedarray_type type;
44         size_t byteOffset = 0;
45         size_t length = 0;
46         void *resultData = nullptr;
47         napi_value resultBuffer = nullptr;
48         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
49         inputEncode_ = static_cast<const unsigned char*>(resultData);
50         unsigned char *rets = EncodeAchieve(inputEncode_, length);
51         if (rets == nullptr) {
52             napi_throw_error(env, "-1", "encode input is null");
53             return nullptr;
54         }
55         void *data = nullptr;
56         napi_value arrayBuffer = nullptr;
57         size_t bufferSize = outputLen;
58         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
59         if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(rets), bufferSize) != EOK) {
60             FreeMemory(rets);
61             HILOG_ERROR("copy ret to arraybuffer error");
62             return nullptr;
63         }
64         napi_value result = nullptr;
65         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
66         FreeMemory(rets);
67         return result;
68     }
69 
70     /* base64 encodeToString */
EncodeToStringSync(napi_env env,napi_value src)71     napi_value Base64::EncodeToStringSync(napi_env env, napi_value src)
72     {
73         napi_typedarray_type type;
74         size_t byteOffset = 0;
75         size_t length = 0;
76         void *resultData = nullptr;
77         napi_value resultBuffer = nullptr;
78         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
79         inputEncode_ = static_cast<const unsigned char*>(resultData);
80         unsigned char *ret = EncodeAchieve(inputEncode_, length);
81         if (ret == nullptr) {
82             FreeMemory(ret);
83             napi_throw_error(env, "-1", "encodeToString input is null");
84             return nullptr;
85         }
86         const char *encString = reinterpret_cast<const char*>(ret);
87         napi_value resultStr = nullptr;
88         napi_create_string_utf8(env, encString, strlen(encString), &resultStr);
89         FreeMemory(ret);
90         return resultStr;
91     }
92 
EncodeAchieve(const unsigned char * input,size_t inputLen)93     unsigned char *Base64::EncodeAchieve(const unsigned char *input, size_t inputLen)
94     {
95         size_t inp = 0;
96         size_t temp = 0;
97         size_t bitWise = 0;
98         unsigned char *ret = nullptr;
99         size_t index = 0;
100         outputLen = (inputLen / TRAGET_THREE) * TRAGET_FOUR;
101         if ((inputLen % TRAGET_THREE) > 0) {
102             outputLen += TRAGET_FOUR;
103         }
104         if (outputLen > 0) {
105             ret = new unsigned char[outputLen + 1];
106             if (memset_s(ret, outputLen + 1, '\0', outputLen + 1) != EOK) {
107                 HILOG_ERROR("encode ret memset_s failed");
108                 FreeMemory(ret);
109                 return nullptr;
110             }
111         } else {
112             HILOG_ERROR("outputLen is error");
113             return nullptr;
114         }
115         if (ret == nullptr) {
116             return ret;
117         }
118         while (inp < inputLen) {
119             temp = 0;
120             bitWise = 0;
121             while (temp < TRAGET_THREE) {
122                 if (inp >= inputLen) {
123                     break;
124                 }
125                 bitWise = ((bitWise << TRAGET_EIGHT) | (input[inp] & XFF_FLG));
126                 inp++;
127                 temp++;
128             }
129             bitWise = (bitWise << ((TRAGET_THREE - temp) * TRAGET_EIGHT));
130             for (size_t i = 0; i < TRAGET_FOUR; i++) {
131                 if (temp < i) {
132                     ret[index++] = BASE[BIT_FLG];
133                 } else {
134                     ret[index++] = BASE[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG];
135                 }
136             }
137         }
138         ret[index] = 0;
139         return ret;
140     }
141 
142     /* base64 decode */
DecodeSync(napi_env env,napi_value src)143     napi_value Base64::DecodeSync(napi_env env, napi_value src)
144     {
145         napi_valuetype valuetype = napi_undefined;
146         napi_typeof(env, src, &valuetype);
147         napi_typedarray_type type;
148         size_t byteOffset = 0;
149         size_t length = 0;
150         void *resultData = nullptr;
151         napi_value resultBuffer = nullptr;
152         char *inputString = nullptr;
153         if (valuetype != napi_valuetype::napi_string) {
154             NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
155         }
156         if (valuetype == napi_valuetype::napi_string) {
157             size_t prolen = 0;
158             napi_get_value_string_utf8(env, src, nullptr, 0, &prolen);
159             if (prolen > 0) {
160                 inputString = new char[prolen + 1];
161                 if (memset_s(inputString, prolen + 1, '\0', prolen + 1) != EOK) {
162                     FreeMemory(inputString);
163                     napi_throw_error(env, "-1", "decode inputString memset_s failed");
164                     return nullptr;
165                 }
166             } else {
167                 napi_throw_error(env, "-2", "prolen is error !");
168                 return nullptr;
169             }
170             if (inputString != nullptr) {
171                 napi_get_value_string_utf8(env, src, inputString, prolen + 1, &prolen);
172                 pret = DecodeAchieve(env, inputString, prolen);
173             }
174         } else if (type == napi_typedarray_type::napi_uint8_array) {
175             inputDecode_ = static_cast<const char*>(resultData);
176             pret = DecodeAchieve(env, inputDecode_, length);
177         }
178         void *data = nullptr;
179         napi_value arrayBuffer = nullptr;
180         size_t bufferSize = decodeOutLen;
181         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
182         if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(pret), bufferSize) != EOK) {
183             FreeMemory(inputString);
184             FreeMemory(pret);
185             HILOG_ERROR("copy retDecode to arraybuffer error");
186             return nullptr;
187         }
188         napi_value result = nullptr;
189         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
190         FreeMemory(inputString);
191         FreeMemory(pret);
192         return result;
193     }
194 
DecodeAchieve(napi_env env,const char * input,size_t inputLen)195     unsigned char *Base64::DecodeAchieve(napi_env env, const char *input, size_t inputLen)
196     {
197         retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE;
198         decodeOutLen = retLen;
199         size_t equalCount = 0;
200         size_t index = 0;
201         size_t inp = 0;
202         size_t temp = 0;
203         size_t bitWise = 0;
204         if (*(input + inputLen - 1) == '=') {
205             equalCount++;
206         }
207         if (*(input + inputLen - TRAGET_TWO) == '=') {
208             equalCount++;
209         }
210         if (*(input + inputLen - TRAGET_THREE) == '=') {
211             equalCount++;
212         }
213         retLen = DecodeOut(equalCount, retLen);
214         if (retLen > 0) {
215             retDecode = new unsigned char[retLen + 1];
216             if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != EOK) {
217                 FreeMemory(retDecode);
218                 napi_throw_error(env, "-1", "decode retDecode memset_s failed");
219                 return nullptr;
220             }
221         } else {
222             napi_throw_error(env, "-2", "retLen is error !");
223             return nullptr;
224         }
225         if (retDecode == nullptr) {
226             return retDecode;
227         }
228         while (inp < (inputLen - equalCount)) {
229             temp = 0;
230             bitWise = 0;
231             while (temp < TRAGET_FOUR) {
232                 if (inp >= (inputLen - equalCount)) {
233                     break;
234                 }
235                 bitWise = (bitWise << TRAGET_SIX) | (Finds(env, input[inp]));
236                 inp++;
237                 temp++;
238             }
239             bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX);
240             for (size_t i = 0; i < TRAGET_THREE; i++) {
241                 if (i == temp) {
242                     break;
243                 }
244                 retDecode[index++] = static_cast<char>((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG);
245             }
246         }
247         retDecode[index] = 0;
248         return retDecode;
249     }
250 
DecodeOut(size_t equalCount,size_t retLen)251     size_t Base64::DecodeOut(size_t equalCount, size_t retLen)
252     {
253         size_t temp = retLen;
254         if (equalCount == 1) {
255             decodeOutLen -= 1;
256         }
257         if (equalCount == TRAGET_TWO) {
258             decodeOutLen -= TRAGET_TWO;
259         }
260         switch (equalCount) {
261             case 0:
262                 temp += TRAGET_FOUR;
263                 break;
264             case 1:
265                 temp += TRAGET_FOUR;
266                 break;
267             case TRAGET_TWO:
268                 temp += TRAGET_THREE;
269                 break;
270             default:
271                 temp += TRAGET_TWO;
272                 break;
273         }
274         return temp;
275     }
276 
277     /* Decoding lookup function */
Finds(napi_env env,char ch)278     size_t Base64::Finds(napi_env env, char ch)
279     {
280         size_t couts = 0;
281         // 65:Number of elements in the encoding table.
282         for (size_t i = 0; i < 65; i++) {
283             if (BASE[i] == ch) {
284                 couts = i;
285                 break;
286             }
287             // 64:Number of elements in the encoding table.
288             if (i == 64 && BASE[i] != ch) {
289                 napi_throw_error(env, "-1", "The input string contains unsupported characters");
290                 return 0;
291             }
292         }
293         return couts;
294     }
295 
Encode(napi_env env,napi_value src)296     napi_value Base64::Encode(napi_env env, napi_value src)
297     {
298         napi_typedarray_type type;
299         size_t byteOffset = 0;
300         size_t length = 0;
301         void *resultData = nullptr;
302         napi_value resultBuffer = nullptr;
303         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
304         unsigned char *inputEncode = nullptr;
305         inputEncode = static_cast<unsigned char*>(resultData);
306         CreateEncodePromise(env, inputEncode, length);
307         return stdEncodeInfo_->promise;
308     }
309 
EncodeToString(napi_env env,napi_value src)310     napi_value Base64::EncodeToString(napi_env env, napi_value src)
311     {
312         napi_typedarray_type type;
313         size_t byteOffset = 0;
314         size_t length = 0;
315         void *resultData = nullptr;
316         napi_value resultBuffer = nullptr;
317         NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
318         unsigned char *inputEncode = nullptr;
319         inputEncode = static_cast<unsigned char*>(resultData);
320         CreateEncodeToStringPromise(env, inputEncode, length);
321         return stdEncodeInfo_->promise;
322     }
323 
CreateEncodePromise(napi_env env,unsigned char * inputDecode,size_t length)324     void Base64::CreateEncodePromise(napi_env env, unsigned char *inputDecode, size_t length)
325     {
326         napi_value resourceName = nullptr;
327         stdEncodeInfo_ = new EncodeInfo();
328         stdEncodeInfo_->sinputEncode = inputDecode;
329         stdEncodeInfo_->slength = length;
330         stdEncodeInfo_->env = env;
331         napi_create_promise(env, &stdEncodeInfo_->deferred, &stdEncodeInfo_->promise);
332         napi_create_string_utf8(env, "ReadStdEncode", NAPI_AUTO_LENGTH, &resourceName);
333         napi_create_async_work(env, nullptr, resourceName, ReadStdEncode, EndStdEncode,
334                                reinterpret_cast<void*>(stdEncodeInfo_), &stdEncodeInfo_->worker);
335         napi_queue_async_work(env, stdEncodeInfo_->worker);
336     }
337 
CreateEncodeToStringPromise(napi_env env,unsigned char * inputDecode,size_t length)338     void Base64::CreateEncodeToStringPromise(napi_env env, unsigned char *inputDecode, size_t length)
339     {
340         napi_value resourceName = nullptr;
341         stdEncodeInfo_ = new EncodeInfo();
342         stdEncodeInfo_->sinputEncode = inputDecode;
343         stdEncodeInfo_->slength = length;
344         napi_create_promise(env, &stdEncodeInfo_->deferred, &stdEncodeInfo_->promise);
345         napi_create_string_utf8(env, "ReadStdEncodeToString", NAPI_AUTO_LENGTH, &resourceName);
346         napi_create_async_work(env, nullptr, resourceName, ReadStdEncodeToString, EndStdEncodeToString,
347                                reinterpret_cast<void*>(stdEncodeInfo_), &stdEncodeInfo_->worker);
348         napi_queue_async_work(env, stdEncodeInfo_->worker);
349     }
350 
EncodeAchieves(napi_env env,EncodeInfo * encodeInfo)351     unsigned char *EncodeAchieves(napi_env env, EncodeInfo *encodeInfo)
352     {
353         const unsigned char *input = encodeInfo->sinputEncode;
354         size_t inputLen = encodeInfo->slength;
355         size_t inp = 0;
356         size_t temp = 0;
357         size_t bitWise = 0;
358         unsigned char *ret = nullptr;
359         size_t index = 0;
360         size_t outputLen = 0;
361         outputLen = (inputLen / TRAGET_THREE) * TRAGET_FOUR;
362         if ((inputLen % TRAGET_THREE) > 0) {
363             outputLen += TRAGET_FOUR;
364         }
365         encodeInfo->soutputLen = outputLen;
366         if (outputLen > 0) {
367             ret = new unsigned char[outputLen + 1];
368             if (memset_s(ret, outputLen + 1, '\0', outputLen + 1) != EOK) {
369                 FreeMemory(ret);
370                 napi_throw_error(encodeInfo->env, "-1", "ret path memset_s failed");
371                 return nullptr;
372             }
373         } else {
374             napi_throw_error(encodeInfo->env, "-2", "outputLen is error !");
375             return nullptr;
376         }
377         if (ret == nullptr) {
378             return ret;
379         }
380         while (inp < inputLen) {
381             temp = 0;
382             bitWise = 0;
383             while (temp < TRAGET_THREE) {
384                 if (inp >= inputLen) {
385                     break;
386                 }
387                 bitWise = ((bitWise << TRAGET_EIGHT) | (input[inp] & XFF_FLG));
388                 inp++;
389                 temp++;
390             }
391             bitWise = (bitWise << ((TRAGET_THREE - temp) * TRAGET_EIGHT));
392             for (size_t i = 0; i < TRAGET_FOUR; i++) {
393                 if (temp < i) {
394                     ret[index++] = BASE[BIT_FLG];
395                 } else {
396                     ret[index++] = BASE[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG];
397                 }
398             }
399         }
400         ret[index] = 0;
401         return ret;
402     }
403 
ReadStdEncode(napi_env env,void * data)404     void Base64::ReadStdEncode(napi_env env, void *data)
405     {
406         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(data);
407         unsigned char *rets = EncodeAchieves(env, stdEncodeInfo);
408         stdEncodeInfo->sinputEncoding = rets;
409     }
410 
EndStdEncode(napi_env env,napi_status status,void * buffer)411     void Base64::EndStdEncode(napi_env env, napi_status status, void *buffer)
412     {
413         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(buffer);
414         void *data = nullptr;
415         napi_value arrayBuffer = nullptr;
416         size_t bufferSize = stdEncodeInfo->soutputLen;
417         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
418         if (memcpy_s(data, bufferSize,
419             reinterpret_cast<const void*>(stdEncodeInfo->sinputEncoding), bufferSize) != EOK) {
420             HILOG_ERROR("copy ret to arraybuffer error");
421             napi_delete_async_work(env, stdEncodeInfo->worker);
422             return;
423         }
424         napi_value result = nullptr;
425         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
426         napi_resolve_deferred(env, stdEncodeInfo->deferred, result);
427         napi_delete_async_work(env, stdEncodeInfo->worker);
428         delete[] stdEncodeInfo->sinputEncoding;
429         delete stdEncodeInfo;
430     }
431 
ReadStdEncodeToString(napi_env env,void * data)432     void Base64::ReadStdEncodeToString(napi_env env, void *data)
433     {
434         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(data);
435         unsigned char *rets = EncodeAchieves(env, stdEncodeInfo);
436         stdEncodeInfo->sinputEncoding = rets;
437     }
438 
EndStdEncodeToString(napi_env env,napi_status status,void * buffer)439     void Base64::EndStdEncodeToString(napi_env env, napi_status status, void *buffer)
440     {
441         auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(buffer);
442         const char *encString = reinterpret_cast<const char*>(stdEncodeInfo->sinputEncoding);
443         napi_value resultStr = nullptr;
444         napi_create_string_utf8(env, encString, strlen(encString), &resultStr);
445         napi_resolve_deferred(env, stdEncodeInfo->deferred, resultStr);
446         napi_delete_async_work(env, stdEncodeInfo->worker);
447         delete[] stdEncodeInfo->sinputEncoding;
448         delete stdEncodeInfo;
449     }
450 
Decode(napi_env env,napi_value src)451     napi_value Base64::Decode(napi_env env, napi_value src)
452     {
453         napi_valuetype valuetype = napi_undefined;
454         napi_typeof(env, src, &valuetype);
455         napi_typedarray_type type;
456         size_t byteOffset = 0;
457         size_t length = 0;
458         void *resultData = nullptr;
459         napi_value resultBuffer = nullptr;
460         char *inputString = nullptr;
461         char *inputDecode = nullptr;
462         if (valuetype != napi_valuetype::napi_string) {
463             NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset));
464         }
465         if (valuetype == napi_valuetype::napi_string) {
466             size_t prolen = 0;
467             napi_get_value_string_utf8(env, src, nullptr, 0, &prolen);
468             if (prolen > 0) {
469                 inputString = new char[prolen + 1];
470                 if (memset_s(inputString, prolen + 1, '\0', prolen + 1) != EOK) {
471                     napi_throw_error(env, "-1", "decode inputString memset_s failed");
472                     return nullptr;
473                 }
474             } else {
475                 napi_throw_error(env, "-2", "prolen is error !");
476                 return nullptr;
477             }
478             napi_get_value_string_utf8(env, src, inputString, prolen + 1, &prolen);
479             CreateDecodePromise(env, inputString, prolen);
480         } else if (type == napi_typedarray_type::napi_uint8_array) {
481             inputDecode = static_cast<char*>(resultData);
482             CreateDecodePromise(env, inputDecode, length);
483         }
484         return stdDecodeInfo_->promise;
485     }
486 
CreateDecodePromise(napi_env env,char * inputDecode,size_t length)487     void Base64::CreateDecodePromise(napi_env env, char *inputDecode, size_t length)
488     {
489         napi_value resourceName = nullptr;
490         stdDecodeInfo_ = new DecodeInfo();
491         stdDecodeInfo_->sinputDecode = inputDecode;
492         stdDecodeInfo_->slength = length;
493         stdDecodeInfo_->env = env;
494         napi_create_promise(env, &stdDecodeInfo_->deferred, &stdDecodeInfo_->promise);
495         napi_create_string_utf8(env, "ReadStdDecode", NAPI_AUTO_LENGTH, &resourceName);
496         napi_create_async_work(env, nullptr, resourceName, ReadStdDecode, EndStdDecode,
497                                reinterpret_cast<void*>(stdDecodeInfo_), &stdDecodeInfo_->worker);
498         napi_queue_async_work(env, stdDecodeInfo_->worker);
499     }
500 
Finds(char ch)501     size_t Finds(char ch)
502     {
503         size_t couts = 0;
504         for (size_t i = 0; i < TRAGET_SIXTYFIVE; i++) {
505             if (BASE[i] == ch) {
506                 couts = i;
507             }
508         }
509         return couts;
510     }
DecodeOut(size_t equalCount,size_t retLen,DecodeInfo * decodeInfo)511     size_t DecodeOut(size_t equalCount, size_t retLen, DecodeInfo *decodeInfo)
512     {
513         if (equalCount == 1) {
514             decodeInfo->decodeOutLen -= 1;
515         }
516         if (equalCount == TRAGET_TWO) {
517             decodeInfo->decodeOutLen -= TRAGET_TWO;
518         }
519         switch (equalCount) {
520             case 0:
521                 retLen += TRAGET_FOUR;
522                 break;
523             case 1:
524                 retLen += TRAGET_FOUR;
525                 break;
526             case TRAGET_TWO:
527                 retLen += TRAGET_THREE;
528                 break;
529             default:
530                 retLen += TRAGET_TWO;
531                 break;
532         }
533         return retLen;
534     }
535 
DecodeAchieves(napi_env env,DecodeInfo * decodeInfo)536     unsigned char *DecodeAchieves(napi_env env, DecodeInfo *decodeInfo)
537     {
538         const char *input = decodeInfo->sinputDecode;
539         size_t inputLen = decodeInfo->slength;
540         size_t retLen = 0;
541         retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE;
542         decodeInfo->decodeOutLen = retLen;
543         size_t equalCount = 0;
544         size_t inp = 0;
545         size_t temp = 0;
546         size_t bitWise = 0;
547         size_t index = 0;
548         unsigned char *retDecode = nullptr;
549         if (*(input + inputLen - 1) == '=') {
550             equalCount++;
551         }
552         if (*(input + inputLen - TRAGET_TWO) == '=') {
553             equalCount++;
554         }
555         retLen = DecodeOut(equalCount, retLen, decodeInfo);
556         if (retLen > 0) {
557             retDecode = new unsigned char[retLen + 1];
558             if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != EOK) {
559                 FreeMemory(retDecode);
560                 napi_throw_error(decodeInfo->env, "-1", "decode retDecode memset_s failed");
561                 return nullptr;
562             }
563         } else {
564             napi_throw_error(decodeInfo->env, "-2", "retLen is error !");
565             return nullptr;
566         }
567         while (inp < (inputLen - equalCount)) {
568             temp = 0;
569             bitWise = 0;
570             while (temp < TRAGET_FOUR) {
571                 if (inp >= (inputLen - equalCount)) {
572                     break;
573                 }
574                 bitWise = (bitWise << TRAGET_SIX) | (Finds(input[inp]));
575                 inp++;
576                 temp++;
577             }
578             bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX);
579             for (size_t i = 0; i < TRAGET_THREE; i++) {
580                 if (i == temp) {
581                     break;
582                 }
583                 retDecode[index++] = static_cast<char>((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG);
584             }
585         }
586         retDecode[index] = 0;
587         return retDecode;
588     }
589 
ReadStdDecode(napi_env env,void * data)590     void Base64::ReadStdDecode(napi_env env, void *data)
591     {
592         auto stdDecodeInfo = reinterpret_cast<DecodeInfo*>(data);
593         unsigned char *rets = DecodeAchieves(env, stdDecodeInfo);
594         stdDecodeInfo->sinputDecoding = rets;
595     }
EndStdDecode(napi_env env,napi_status status,void * buffer)596     void Base64::EndStdDecode(napi_env env, napi_status status, void *buffer)
597     {
598         auto stdDecodeInfo = reinterpret_cast<DecodeInfo*>(buffer);
599         void *data = nullptr;
600         napi_value arrayBuffer = nullptr;
601         size_t bufferSize = stdDecodeInfo->decodeOutLen;
602         napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer);
603         if (memcpy_s(data, bufferSize,
604             reinterpret_cast<const void*>(stdDecodeInfo->sinputDecoding), bufferSize) != EOK) {
605             HILOG_ERROR("copy ret to arraybuffer error");
606             napi_delete_async_work(env, stdDecodeInfo->worker);
607             return;
608         }
609         napi_value result = nullptr;
610         napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result);
611         napi_resolve_deferred(env, stdDecodeInfo->deferred, result);
612         napi_delete_async_work(env, stdDecodeInfo->worker);
613         delete[] stdDecodeInfo->sinputDecoding;
614         delete stdDecodeInfo;
615     }
616 
617     /* Memory cleanup function */
FreeMemory(char * address)618     void FreeMemory(char *address)
619     {
620         if (address != nullptr) {
621             delete[] address;
622         }
623     }
FreeMemory(unsigned char * address)624     void FreeMemory(unsigned char *address)
625     {
626         if (address != nullptr) {
627             delete[] address;
628         }
629     }
630 }
631