Skip to content

Commit 68bb1e9

Browse files
addaleaxBridgeAR
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 240de93 commit 68bb1e9

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
@@ -287,18 +287,19 @@ size_t StringBytes::WriteUCS2(Isolate* isolate,
287287
CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);
288288

289289
// Write all but the last char
290+
max_chars = std::min(max_chars, static_cast<size_t>(str->Length()));
291+
if (max_chars == 0) return 0;
290292
nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
293+
CHECK_EQ(nchars, max_chars - 1);
291294

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

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

303304
*chars_written = nchars;
304305
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)