From c4686fa5a7c0e6ad1e118c30e01ebfec7c7a8be5 Mon Sep 17 00:00:00 2001 From: James M Snell Date: Wed, 11 Aug 2021 08:55:28 -0700 Subject: [PATCH] src: fix TextDecoder final flush size calculation Flushing a TextDecoder with a zero-sized input and pending incomplete characters was failing when fatal: false. Signed-off-by: James M Snell PR-URL: https://github.com/nodejs/node/pull/39737 Reviewed-By: Robert Nagy Reviewed-By: Matteo Collina --- src/node_i18n.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/node_i18n.cc b/src/node_i18n.cc index 63a6db7a49bc64..e4bc79ebc20800 100644 --- a/src/node_i18n.cc +++ b/src/node_i18n.cc @@ -441,11 +441,24 @@ void ConverterObject::Decode(const FunctionCallbackInfo& args) { UErrorCode status = U_ZERO_ERROR; MaybeStackBuffer result; MaybeLocal ret; - size_t limit = converter->min_char_size() * input.length(); + + UBool flush = (flags & CONVERTER_FLAGS_FLUSH) == CONVERTER_FLAGS_FLUSH; + + // When flushing the final chunk, the limit is the maximum + // of either the input buffer length or the number of pending + // characters times the min char size. + size_t limit = converter->min_char_size() * + (!flush ? + input.length() : + std::max( + input.length(), + static_cast( + ucnv_toUCountPending(converter->conv(), &status)))); + status = U_ZERO_ERROR; + if (limit > 0) result.AllocateSufficientStorage(limit); - UBool flush = (flags & CONVERTER_FLAGS_FLUSH) == CONVERTER_FLAGS_FLUSH; auto cleanup = OnScopeLeave([&]() { if (flush) { // Reset the converter state.