Skip to content

Commit ff647fd

Browse files
addaleaxBethGriggs
authored andcommitted
buffer: do not affect memory after target for utf16 write
Do not write one character too much before shifting the whole result to the left when using UTF16-LE, possibly overwriting already-used memory while doing so. Fixes: #26422 PR-URL: #26432 Fixes: #26422 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
1 parent 44f6260 commit ff647fd

File tree

2 files changed

+14
-5
lines changed

2 files changed

+14
-5
lines changed

src/string_bytes.cc

+6-5
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,19 @@ size_t StringBytes::WriteUCS2(Isolate* isolate,
286286
CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);
287287

288288
// Write all but the last char
289+
max_chars = std::min(max_chars, static_cast<size_t>(str->Length()));
290+
if (max_chars == 0) return 0;
289291
nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
292+
CHECK_EQ(nchars, max_chars - 1);
290293

291294
// Shift everything to unaligned-left
292295
memmove(dst, aligned_dst, nchars * sizeof(*dst));
293296

294297
// One more char to be written
295298
uint16_t last;
296-
if (nchars == max_chars - 1 &&
297-
str->Write(isolate, &last, nchars, 1, flags) != 0) {
298-
memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
299-
nchars++;
300-
}
299+
CHECK_EQ(str->Write(isolate, &last, nchars, 1, flags), 1);
300+
memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
301+
nchars++;
301302

302303
*chars_written = nchars;
303304
return nchars * sizeof(*dst);

test/parallel/test-buffer-write.js

+8
Original file line numberDiff line numberDiff line change
@@ -91,3 +91,11 @@ assert.strictEqual(Buffer.compare(z, Buffer.alloc(4, 0)), 0);
9191
// Large overrun could corrupt the process
9292
assert.strictEqual(Buffer.alloc(4)
9393
.write('ыыыыыы'.repeat(100), 3, 'utf16le'), 0);
94+
95+
{
96+
// .write() does not affect the byte after the written-to slice of the Buffer.
97+
// Refs: https://github.com/nodejs/node/issues/26422
98+
const buf = Buffer.alloc(8);
99+
assert.strictEqual(buf.write('ыы', 1, 'utf16le'), 4);
100+
assert.deepStrictEqual([...buf], [0, 0x4b, 0x04, 0x4b, 0x04, 0, 0, 0]);
101+
}

0 commit comments

Comments
 (0)