buffer: fix unaligned UTF-16LE decoding

For odd-length input, the destination only has room for complete code
units. Copy those units and ignore the trailing byte. This matches the
aligned and big-endian paths.

Assisted-by: pi
Signed-off-by: Matteo Collina <hello@matteocollina.com>
PR-URL: https://github.com/nodejs/node/pull/65905
Reviewed-By: Gürgün Dayıoğlu <hey@gurgun.day>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Robert Nagy <ronagy@icloud.com>
This commit is contained in:
Matteo Collina authored and GitHub committed 2026-09-10 07:21:44 +00:00
1 parent 43d3fe9558
commit b805fb5158
2 files changed
+9 -2

No files matched your search

+2 -2
View File
@@ -751,8 +751,8 @@ MaybeLocal<Value> StringBytes::Encode(Isolate* isolate,
}
if (reinterpret_cast<uintptr_t>(buf) % 2 != 0) {
return EncodeTwoByteString(
isolate, str_len, [buf, buflen](uint16_t* dst) {
memcpy(dst, buf, buflen);
isolate, str_len, [buf, str_len](uint16_t* dst) {
memcpy(dst, buf, str_len * sizeof(*dst));
});
}
return ExternTwoByteString::NewFromCopy(
+7
View File
@@ -9,6 +9,13 @@ for (const encoding of ['utf8', 'utf-8', 'ucs2', 'ucs-2', 'ascii', 'latin1',
assert.strictEqual(Buffer.from('foo', encoding).toString(encoding), 'foo');
}
// Ignore an incomplete trailing code unit when decoding unaligned UTF-16LE.
for (const size of [514, 516]) {
const buffer = Buffer.alloc(size, 0x61);
assert.strictEqual(buffer.toString('utf16le', 1),
'\u6161'.repeat((size - 1) >>> 1));
}
// base64
['base64', 'BASE64'].forEach((encoding) => {
assert.strictEqual(Buffer.from('Zm9v', encoding).toString(encoding), 'Zm9v');