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 if (pret == nullptr) { 179 if (inputString != nullptr) { 180 FreeMemory(inputString); 181 } 182 return nullptr; 183 } 184 void *data = nullptr; 185 napi_value arrayBuffer = nullptr; 186 size_t bufferSize = decodeOutLen; 187 napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer); 188 if (memcpy_s(data, bufferSize, reinterpret_cast<const void*>(pret), bufferSize) != EOK) { 189 FreeMemory(inputString); 190 FreeMemory(pret); 191 HILOG_ERROR("copy retDecode to arraybuffer error"); 192 return nullptr; 193 } 194 napi_value result = nullptr; 195 napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result); 196 FreeMemory(inputString); 197 FreeMemory(pret); 198 return result; 199 } 200 DecodeAchieve(napi_env env,const char * input,size_t inputLen)201 unsigned char *Base64::DecodeAchieve(napi_env env, const char *input, size_t inputLen) 202 { 203 retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE; 204 decodeOutLen = retLen; 205 size_t equalCount = 0; 206 size_t index = 0; 207 size_t inp = 0; 208 size_t temp = 0; 209 size_t bitWise = 0; 210 if (*(input + inputLen - 1) == '=') { 211 equalCount++; 212 } 213 if (*(input + inputLen - TRAGET_TWO) == '=') { 214 equalCount++; 215 } 216 if (*(input + inputLen - TRAGET_THREE) == '=') { 217 equalCount++; 218 } 219 retLen = DecodeOut(equalCount, retLen); 220 if (retLen > 0) { 221 retDecode = new unsigned char[retLen + 1]; 222 if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != EOK) { 223 FreeMemory(retDecode); 224 napi_throw_error(env, "-1", "decode retDecode memset_s failed"); 225 return nullptr; 226 } 227 } else { 228 napi_throw_error(env, "-2", "retLen is error !"); 229 return nullptr; 230 } 231 if (retDecode == nullptr) { 232 return retDecode; 233 } 234 while (inp < (inputLen - equalCount)) { 235 temp = 0; 236 bitWise = 0; 237 while (temp < TRAGET_FOUR) { 238 if (inp >= (inputLen - equalCount)) { 239 break; 240 } 241 int findsData = Finds(env, input[inp]); 242 if (findsData == -1) { 243 FreeMemory(retDecode); 244 return nullptr; 245 } 246 bitWise = (bitWise << TRAGET_SIX) | static_cast<size_t>(findsData); 247 inp++; 248 temp++; 249 } 250 bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX); 251 for (size_t i = 0; i < TRAGET_THREE; i++) { 252 if (i == temp) { 253 break; 254 } 255 retDecode[index++] = static_cast<char>((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG); 256 } 257 } 258 retDecode[index] = 0; 259 return retDecode; 260 } 261 DecodeOut(size_t equalCount,size_t retLen)262 size_t Base64::DecodeOut(size_t equalCount, size_t retLen) 263 { 264 size_t temp = retLen; 265 if (equalCount == 1) { 266 decodeOutLen -= 1; 267 } 268 if (equalCount == TRAGET_TWO) { 269 decodeOutLen -= TRAGET_TWO; 270 } 271 switch (equalCount) { 272 case 0: 273 temp += TRAGET_FOUR; 274 break; 275 case 1: 276 temp += TRAGET_FOUR; 277 break; 278 case TRAGET_TWO: 279 temp += TRAGET_THREE; 280 break; 281 default: 282 temp += TRAGET_TWO; 283 break; 284 } 285 return temp; 286 } 287 288 /* Decoding lookup function */ Finds(napi_env env,char ch)289 int Base64::Finds(napi_env env, char ch) 290 { 291 int couts = 0; 292 // 65:Number of elements in the encoding table. 293 for (int i = 0; i < 65; i++) { 294 if (BASE[i] == ch) { 295 couts = i; 296 break; 297 } 298 // 64:Number of elements in the encoding table. 299 if (i == 64 && BASE[i] != ch) { 300 napi_throw_error(env, "-1", "The input string contains unsupported characters"); 301 return -1; 302 } 303 } 304 return couts; 305 } 306 Encode(napi_env env,napi_value src)307 napi_value Base64::Encode(napi_env env, napi_value src) 308 { 309 napi_typedarray_type type; 310 size_t byteOffset = 0; 311 size_t length = 0; 312 void *resultData = nullptr; 313 napi_value resultBuffer = nullptr; 314 NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset)); 315 unsigned char *inputEncode = nullptr; 316 inputEncode = static_cast<unsigned char*>(resultData); 317 CreateEncodePromise(env, inputEncode, length); 318 return stdEncodeInfo_->promise; 319 } 320 EncodeToString(napi_env env,napi_value src)321 napi_value Base64::EncodeToString(napi_env env, napi_value src) 322 { 323 napi_typedarray_type type; 324 size_t byteOffset = 0; 325 size_t length = 0; 326 void *resultData = nullptr; 327 napi_value resultBuffer = nullptr; 328 NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset)); 329 unsigned char *inputEncode = nullptr; 330 inputEncode = static_cast<unsigned char*>(resultData); 331 CreateEncodeToStringPromise(env, inputEncode, length); 332 return stdEncodeInfo_->promise; 333 } 334 CreateEncodePromise(napi_env env,unsigned char * inputDecode,size_t length)335 void Base64::CreateEncodePromise(napi_env env, unsigned char *inputDecode, size_t length) 336 { 337 napi_value resourceName = nullptr; 338 stdEncodeInfo_ = new EncodeInfo(); 339 stdEncodeInfo_->sinputEncode = inputDecode; 340 stdEncodeInfo_->slength = length; 341 stdEncodeInfo_->env = env; 342 napi_create_promise(env, &stdEncodeInfo_->deferred, &stdEncodeInfo_->promise); 343 napi_create_string_utf8(env, "ReadStdEncode", NAPI_AUTO_LENGTH, &resourceName); 344 napi_create_async_work(env, nullptr, resourceName, ReadStdEncode, EndStdEncode, 345 reinterpret_cast<void*>(stdEncodeInfo_), &stdEncodeInfo_->worker); 346 napi_queue_async_work_with_qos(env, stdEncodeInfo_->worker, napi_qos_user_initiated); 347 } 348 CreateEncodeToStringPromise(napi_env env,unsigned char * inputDecode,size_t length)349 void Base64::CreateEncodeToStringPromise(napi_env env, unsigned char *inputDecode, size_t length) 350 { 351 napi_value resourceName = nullptr; 352 stdEncodeInfo_ = new EncodeInfo(); 353 stdEncodeInfo_->sinputEncode = inputDecode; 354 stdEncodeInfo_->slength = length; 355 napi_create_promise(env, &stdEncodeInfo_->deferred, &stdEncodeInfo_->promise); 356 napi_create_string_utf8(env, "ReadStdEncodeToString", NAPI_AUTO_LENGTH, &resourceName); 357 napi_create_async_work(env, nullptr, resourceName, ReadStdEncodeToString, EndStdEncodeToString, 358 reinterpret_cast<void*>(stdEncodeInfo_), &stdEncodeInfo_->worker); 359 napi_queue_async_work_with_qos(env, stdEncodeInfo_->worker, napi_qos_user_initiated); 360 } 361 EncodeAchieves(napi_env env,EncodeInfo * encodeInfo)362 unsigned char *EncodeAchieves(napi_env env, EncodeInfo *encodeInfo) 363 { 364 const unsigned char *input = encodeInfo->sinputEncode; 365 size_t inputLen = encodeInfo->slength; 366 size_t inp = 0; 367 size_t temp = 0; 368 size_t bitWise = 0; 369 unsigned char *ret = nullptr; 370 size_t index = 0; 371 size_t outputLen = 0; 372 outputLen = (inputLen / TRAGET_THREE) * TRAGET_FOUR; 373 if ((inputLen % TRAGET_THREE) > 0) { 374 outputLen += TRAGET_FOUR; 375 } 376 encodeInfo->soutputLen = outputLen; 377 if (outputLen > 0) { 378 ret = new unsigned char[outputLen + 1]; 379 if (memset_s(ret, outputLen + 1, '\0', outputLen + 1) != EOK) { 380 FreeMemory(ret); 381 napi_throw_error(encodeInfo->env, "-1", "ret path memset_s failed"); 382 return nullptr; 383 } 384 } else { 385 napi_throw_error(encodeInfo->env, "-2", "outputLen is error !"); 386 return nullptr; 387 } 388 if (ret == nullptr) { 389 return ret; 390 } 391 while (inp < inputLen) { 392 temp = 0; 393 bitWise = 0; 394 while (temp < TRAGET_THREE) { 395 if (inp >= inputLen) { 396 break; 397 } 398 bitWise = ((bitWise << TRAGET_EIGHT) | (input[inp] & XFF_FLG)); 399 inp++; 400 temp++; 401 } 402 bitWise = (bitWise << ((TRAGET_THREE - temp) * TRAGET_EIGHT)); 403 for (size_t i = 0; i < TRAGET_FOUR; i++) { 404 if (temp < i) { 405 ret[index++] = BASE[BIT_FLG]; 406 } else { 407 ret[index++] = BASE[(bitWise >> ((TRAGET_THREE - i) * TRAGET_SIX)) & SIXTEEN_FLG]; 408 } 409 } 410 } 411 ret[index] = 0; 412 return ret; 413 } 414 ReadStdEncode(napi_env env,void * data)415 void Base64::ReadStdEncode(napi_env env, void *data) 416 { 417 auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(data); 418 unsigned char *rets = EncodeAchieves(env, stdEncodeInfo); 419 stdEncodeInfo->sinputEncoding = rets; 420 } 421 EndStdEncode(napi_env env,napi_status status,void * buffer)422 void Base64::EndStdEncode(napi_env env, napi_status status, void *buffer) 423 { 424 auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(buffer); 425 void *data = nullptr; 426 napi_handle_scope scope = nullptr; 427 napi_open_handle_scope(env, &scope); 428 if (scope == nullptr) { 429 return; 430 } 431 napi_value arrayBuffer = nullptr; 432 size_t bufferSize = stdEncodeInfo->soutputLen; 433 napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer); 434 if (memcpy_s(data, bufferSize, 435 reinterpret_cast<const void*>(stdEncodeInfo->sinputEncoding), bufferSize) != EOK) { 436 HILOG_ERROR("copy ret to arraybuffer error"); 437 napi_delete_async_work(env, stdEncodeInfo->worker); 438 return; 439 } 440 napi_value result = nullptr; 441 napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result); 442 napi_resolve_deferred(env, stdEncodeInfo->deferred, result); 443 napi_delete_async_work(env, stdEncodeInfo->worker); 444 napi_close_handle_scope(env, scope); 445 delete[] stdEncodeInfo->sinputEncoding; 446 delete stdEncodeInfo; 447 } 448 ReadStdEncodeToString(napi_env env,void * data)449 void Base64::ReadStdEncodeToString(napi_env env, void *data) 450 { 451 auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(data); 452 unsigned char *rets = EncodeAchieves(env, stdEncodeInfo); 453 stdEncodeInfo->sinputEncoding = rets; 454 } 455 EndStdEncodeToString(napi_env env,napi_status status,void * buffer)456 void Base64::EndStdEncodeToString(napi_env env, napi_status status, void *buffer) 457 { 458 auto stdEncodeInfo = reinterpret_cast<EncodeInfo*>(buffer); 459 napi_handle_scope scope = nullptr; 460 napi_open_handle_scope(env, &scope); 461 if (scope == nullptr) { 462 return; 463 } 464 const char *encString = reinterpret_cast<const char*>(stdEncodeInfo->sinputEncoding); 465 napi_value resultStr = nullptr; 466 napi_create_string_utf8(env, encString, strlen(encString), &resultStr); 467 napi_resolve_deferred(env, stdEncodeInfo->deferred, resultStr); 468 napi_delete_async_work(env, stdEncodeInfo->worker); 469 napi_close_handle_scope(env, scope); 470 delete[] stdEncodeInfo->sinputEncoding; 471 delete stdEncodeInfo; 472 } 473 Decode(napi_env env,napi_value src)474 napi_value Base64::Decode(napi_env env, napi_value src) 475 { 476 napi_valuetype valuetype = napi_undefined; 477 napi_typeof(env, src, &valuetype); 478 napi_typedarray_type type; 479 size_t byteOffset = 0; 480 size_t length = 0; 481 void *resultData = nullptr; 482 napi_value resultBuffer = nullptr; 483 char *inputString = nullptr; 484 char *inputDecode = nullptr; 485 if (valuetype != napi_valuetype::napi_string) { 486 NAPI_CALL(env, napi_get_typedarray_info(env, src, &type, &length, &resultData, &resultBuffer, &byteOffset)); 487 } 488 if (valuetype == napi_valuetype::napi_string) { 489 size_t prolen = 0; 490 napi_get_value_string_utf8(env, src, nullptr, 0, &prolen); 491 if (prolen > 0) { 492 inputString = new char[prolen + 1]; 493 if (memset_s(inputString, prolen + 1, '\0', prolen + 1) != EOK) { 494 napi_throw_error(env, "-1", "decode inputString memset_s failed"); 495 return nullptr; 496 } 497 } else { 498 napi_throw_error(env, "-2", "prolen is error !"); 499 return nullptr; 500 } 501 napi_get_value_string_utf8(env, src, inputString, prolen + 1, &prolen); 502 CreateDecodePromise(env, inputString, prolen); 503 } else if (type == napi_typedarray_type::napi_uint8_array) { 504 inputDecode = static_cast<char*>(resultData); 505 CreateDecodePromise(env, inputDecode, length); 506 } 507 return stdDecodeInfo_->promise; 508 } 509 CreateDecodePromise(napi_env env,char * inputDecode,size_t length)510 void Base64::CreateDecodePromise(napi_env env, char *inputDecode, size_t length) 511 { 512 napi_value resourceName = nullptr; 513 stdDecodeInfo_ = new DecodeInfo(); 514 stdDecodeInfo_->sinputDecode = inputDecode; 515 stdDecodeInfo_->slength = length; 516 stdDecodeInfo_->env = env; 517 napi_create_promise(env, &stdDecodeInfo_->deferred, &stdDecodeInfo_->promise); 518 napi_create_string_utf8(env, "ReadStdDecode", NAPI_AUTO_LENGTH, &resourceName); 519 napi_create_async_work(env, nullptr, resourceName, ReadStdDecode, EndStdDecode, 520 reinterpret_cast<void*>(stdDecodeInfo_), &stdDecodeInfo_->worker); 521 napi_queue_async_work_with_qos(env, stdDecodeInfo_->worker, napi_qos_user_initiated); 522 } 523 Finds(char ch)524 size_t Finds(char ch) 525 { 526 size_t couts = 0; 527 for (size_t i = 0; i < TRAGET_SIXTYFIVE; i++) { 528 if (BASE[i] == ch) { 529 couts = i; 530 } 531 } 532 return couts; 533 } DecodeOut(size_t equalCount,size_t retLen,DecodeInfo * decodeInfo)534 size_t DecodeOut(size_t equalCount, size_t retLen, DecodeInfo *decodeInfo) 535 { 536 if (equalCount == 1) { 537 decodeInfo->decodeOutLen -= 1; 538 } 539 if (equalCount == TRAGET_TWO) { 540 decodeInfo->decodeOutLen -= TRAGET_TWO; 541 } 542 switch (equalCount) { 543 case 0: 544 retLen += TRAGET_FOUR; 545 break; 546 case 1: 547 retLen += TRAGET_FOUR; 548 break; 549 case TRAGET_TWO: 550 retLen += TRAGET_THREE; 551 break; 552 default: 553 retLen += TRAGET_TWO; 554 break; 555 } 556 return retLen; 557 } 558 DecodeAchieves(napi_env env,DecodeInfo * decodeInfo)559 unsigned char *DecodeAchieves(napi_env env, DecodeInfo *decodeInfo) 560 { 561 const char *input = decodeInfo->sinputDecode; 562 size_t inputLen = decodeInfo->slength; 563 size_t retLen = 0; 564 retLen = (inputLen / TRAGET_FOUR) * TRAGET_THREE; 565 decodeInfo->decodeOutLen = retLen; 566 size_t equalCount = 0; 567 size_t inp = 0; 568 size_t temp = 0; 569 size_t bitWise = 0; 570 size_t index = 0; 571 unsigned char *retDecode = nullptr; 572 if (*(input + inputLen - 1) == '=') { 573 equalCount++; 574 } 575 if (*(input + inputLen - TRAGET_TWO) == '=') { 576 equalCount++; 577 } 578 retLen = DecodeOut(equalCount, retLen, decodeInfo); 579 if (retLen > 0) { 580 retDecode = new unsigned char[retLen + 1]; 581 if (memset_s(retDecode, retLen + 1, '\0', retLen + 1) != EOK) { 582 FreeMemory(retDecode); 583 napi_throw_error(decodeInfo->env, "-1", "decode retDecode memset_s failed"); 584 return nullptr; 585 } 586 } else { 587 napi_throw_error(decodeInfo->env, "-2", "retLen is error !"); 588 return nullptr; 589 } 590 while (inp < (inputLen - equalCount)) { 591 temp = 0; 592 bitWise = 0; 593 while (temp < TRAGET_FOUR) { 594 if (inp >= (inputLen - equalCount)) { 595 break; 596 } 597 bitWise = (bitWise << TRAGET_SIX) | (Finds(input[inp])); 598 inp++; 599 temp++; 600 } 601 bitWise = bitWise << ((TRAGET_FOUR - temp) * TRAGET_SIX); 602 for (size_t i = 0; i < TRAGET_THREE; i++) { 603 if (i == temp) { 604 break; 605 } 606 retDecode[index++] = static_cast<char>((bitWise >> ((TRAGET_TWO - i) * TRAGET_EIGHT)) & XFF_FLG); 607 } 608 } 609 retDecode[index] = 0; 610 return retDecode; 611 } 612 ReadStdDecode(napi_env env,void * data)613 void Base64::ReadStdDecode(napi_env env, void *data) 614 { 615 auto stdDecodeInfo = reinterpret_cast<DecodeInfo*>(data); 616 unsigned char *rets = DecodeAchieves(env, stdDecodeInfo); 617 stdDecodeInfo->sinputDecoding = rets; 618 } EndStdDecode(napi_env env,napi_status status,void * buffer)619 void Base64::EndStdDecode(napi_env env, napi_status status, void *buffer) 620 { 621 auto stdDecodeInfo = reinterpret_cast<DecodeInfo*>(buffer); 622 void *data = nullptr; 623 napi_handle_scope scope = nullptr; 624 napi_open_handle_scope(env, &scope); 625 if (scope == nullptr) { 626 return; 627 } 628 napi_value arrayBuffer = nullptr; 629 size_t bufferSize = stdDecodeInfo->decodeOutLen; 630 napi_create_arraybuffer(env, bufferSize, &data, &arrayBuffer); 631 if (memcpy_s(data, bufferSize, 632 reinterpret_cast<const void*>(stdDecodeInfo->sinputDecoding), bufferSize) != EOK) { 633 HILOG_ERROR("copy ret to arraybuffer error"); 634 napi_delete_async_work(env, stdDecodeInfo->worker); 635 return; 636 } 637 napi_value result = nullptr; 638 napi_create_typedarray(env, napi_uint8_array, bufferSize, arrayBuffer, 0, &result); 639 napi_resolve_deferred(env, stdDecodeInfo->deferred, result); 640 napi_delete_async_work(env, stdDecodeInfo->worker); 641 napi_close_handle_scope(env, scope); 642 delete[] stdDecodeInfo->sinputDecoding; 643 delete stdDecodeInfo; 644 } 645 646 /* Memory cleanup function */ FreeMemory(char * address)647 void FreeMemory(char *address) 648 { 649 if (address != nullptr) { 650 delete[] address; 651 } 652 } FreeMemory(unsigned char * address)653 void FreeMemory(unsigned char *address) 654 { 655 if (address != nullptr) { 656 delete[] address; 657 } 658 } 659 } 660