diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 7a13f35d2f2bcb..fcb08e7cb89ebf 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -42,6 +42,7 @@ #include "node_i18n.h" #include "node_external_reference.h" +#include "simdutf.h" #if defined(NODE_HAVE_I18N_SUPPORT) @@ -222,25 +223,21 @@ MaybeLocal TranscodeUcs2FromUtf8(Environment* env, const size_t source_length, UErrorCode* status) { *status = U_ZERO_ERROR; - MaybeStackBuffer destbuf; - int32_t result_length; - u_strFromUTF8(*destbuf, destbuf.capacity(), &result_length, - source, source_length, status); MaybeLocal ret; - if (U_SUCCESS(*status)) { - destbuf.SetLength(result_length); - ret = ToBufferEndian(env, &destbuf); - } else if (*status == U_BUFFER_OVERFLOW_ERROR) { - *status = U_ZERO_ERROR; - destbuf.AllocateSufficientStorage(result_length); - u_strFromUTF8(*destbuf, result_length, &result_length, - source, source_length, status); - if (U_SUCCESS(*status)) { - destbuf.SetLength(result_length); - ret = ToBufferEndian(env, &destbuf); - } + size_t expected_utf16_length = + simdutf::utf16_length_from_utf8(source, source_length); + MaybeStackBuffer destbuf(expected_utf16_length); + auto actual_length = + simdutf::convert_utf8_to_utf16le(source, source_length, destbuf.out()); + + if (actual_length == 0) { + *status = U_INVALID_CHAR_FOUND; + return ret; } - return ret; + + CHECK_EQ(actual_length, expected_utf16_length); + + return ToBufferEndian(env, &destbuf); } MaybeLocal TranscodeUtf8FromUcs2(Environment* env, @@ -252,26 +249,23 @@ MaybeLocal TranscodeUtf8FromUcs2(Environment* env, *status = U_ZERO_ERROR; MaybeLocal ret; const size_t length_in_chars = source_length / sizeof(UChar); - int32_t result_length; - MaybeStackBuffer sourcebuf; - MaybeStackBuffer destbuf; - CopySourceBuffer(&sourcebuf, source, source_length, length_in_chars); - u_strToUTF8(*destbuf, destbuf.capacity(), &result_length, - *sourcebuf, length_in_chars, status); - if (U_SUCCESS(*status)) { - destbuf.SetLength(result_length); - ret = ToBufferEndian(env, &destbuf); - } else if (*status == U_BUFFER_OVERFLOW_ERROR) { - *status = U_ZERO_ERROR; - destbuf.AllocateSufficientStorage(result_length); - u_strToUTF8(*destbuf, result_length, &result_length, *sourcebuf, - length_in_chars, status); - if (U_SUCCESS(*status)) { - destbuf.SetLength(result_length); - ret = ToBufferEndian(env, &destbuf); - } + size_t expected_utf8_length = simdutf::utf8_length_from_utf16le( + reinterpret_cast(source), length_in_chars); + + MaybeStackBuffer destbuf(expected_utf8_length); + auto actual_length = simdutf::convert_utf16le_to_utf8( + reinterpret_cast(source), + length_in_chars, + destbuf.out()); + + if (actual_length == 0) { + *status = U_INVALID_CHAR_FOUND; + return ret; } - return ret; + + CHECK_EQ(actual_length, expected_utf8_length); + + return ToBufferEndian(env, &destbuf); } const char* EncodingName(const enum encoding encoding) {