From ffe0dc5b87c54046927cb6f9b907b74697002227 Mon Sep 17 00:00:00 2001 From: Yagiz Nizipli Date: Mon, 23 Sep 2024 18:49:53 -0400 Subject: [PATCH] string_decoder: refactor encoding validation PR-URL: https://github.com/nodejs/node/pull/54957 Reviewed-By: Robert Nagy Reviewed-By: James M Snell Reviewed-By: Trivikram Kamat --- lib/internal/util.js | 9 ++++++--- lib/string_decoder.js | 32 ++++++-------------------------- 2 files changed, 12 insertions(+), 29 deletions(-) diff --git a/lib/internal/util.js b/lib/internal/util.js index 9141811afa2..8af23a4eb22 100644 --- a/lib/internal/util.js +++ b/lib/internal/util.js @@ -197,9 +197,12 @@ function assertCrypto() { throw new ERR_NO_CRYPTO(); } -// Return undefined if there is no match. -// Move the "slow cases" to a separate function to make sure this function gets -// inlined properly. That prioritizes the common case. +/** + * Move the "slow cases" to a separate function to make sure this function gets + * inlined properly. That prioritizes the common case. + * @param {unknown} enc + * @returns {string | undefined} Returns undefined if there is no match. + */ function normalizeEncoding(enc) { if (enc == null || enc === 'utf8' || enc === 'utf-8') return 'utf8'; return slowCases(enc); diff --git a/lib/string_decoder.js b/lib/string_decoder.js index c0dbfe2b5e9..842dc3e10e7 100644 --- a/lib/string_decoder.js +++ b/lib/string_decoder.js @@ -40,38 +40,17 @@ const { flush, } = internalBinding('string_decoder'); const { - kIsEncodingSymbol, encodingsMap, - normalizeEncoding: _normalizeEncoding, + normalizeEncoding, } = require('internal/util'); const { ERR_INVALID_ARG_TYPE, ERR_INVALID_THIS, ERR_UNKNOWN_ENCODING, } = require('internal/errors').codes; -const isEncoding = Buffer[kIsEncodingSymbol]; const kNativeDecoder = Symbol('kNativeDecoder'); -// Do not cache `Buffer.isEncoding` when checking encoding names as some -// modules monkey-patch it to support additional encodings -/** - * Normalize encoding notation - * @param {string} enc - * @returns {"utf8" | "utf16le" | "hex" | "ascii" - * | "base64" | "latin1" | "base64url"} - * @throws {TypeError} Throws an error when encoding is invalid - */ -function normalizeEncoding(enc) { - const nenc = _normalizeEncoding(enc); - if (nenc === undefined) { - if (Buffer.isEncoding === isEncoding || !Buffer.isEncoding(enc)) - throw new ERR_UNKNOWN_ENCODING(enc); - return enc; - } - return nenc; -} - /** * StringDecoder provides an interface for efficiently splitting a series of * buffers into a series of JS strings without breaking apart multi-byte @@ -80,6 +59,9 @@ function normalizeEncoding(enc) { */ function StringDecoder(encoding) { this.encoding = normalizeEncoding(encoding); + if (this.encoding === undefined) { + throw new ERR_UNKNOWN_ENCODING(encoding); + } this[kNativeDecoder] = Buffer.alloc(kSize); this[kNativeDecoder][kEncodingField] = encodingsMap[this.encoding]; } @@ -112,11 +94,9 @@ StringDecoder.prototype.write = function write(buf) { * @returns {string} */ StringDecoder.prototype.end = function end(buf) { - let ret = ''; - if (buf !== undefined) - ret = this.write(buf); + const ret = buf === undefined ? '' : this.write(buf); if (this[kNativeDecoder][kBufferedBytes] > 0) - ret += flush(this[kNativeDecoder]); + return ret + flush(this[kNativeDecoder]); return ret; };