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: https://github.com/nodejs/node/issues/26422 PR-URL: https://github.com/nodejs/node/pull/26432 Fixes: https://github.com/nodejs/node/issues/26422 Reviewed-By: Richard Lau <riclau@uk.ibm.com> Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de> Reviewed-By: Minwoo Jung <minwoo@nodesource.com>
This commit is contained in:
parent
ceb73e714a
commit
31147c4704
@ -287,18 +287,19 @@ size_t StringBytes::WriteUCS2(Isolate* isolate,
|
|||||||
CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);
|
CHECK_EQ(reinterpret_cast<uintptr_t>(aligned_dst) % sizeof(*dst), 0);
|
||||||
|
|
||||||
// Write all but the last char
|
// Write all but the last char
|
||||||
|
max_chars = std::min(max_chars, static_cast<size_t>(str->Length()));
|
||||||
|
if (max_chars == 0) return 0;
|
||||||
nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
|
nchars = str->Write(isolate, aligned_dst, 0, max_chars - 1, flags);
|
||||||
|
CHECK_EQ(nchars, max_chars - 1);
|
||||||
|
|
||||||
// Shift everything to unaligned-left
|
// Shift everything to unaligned-left
|
||||||
memmove(dst, aligned_dst, nchars * sizeof(*dst));
|
memmove(dst, aligned_dst, nchars * sizeof(*dst));
|
||||||
|
|
||||||
// One more char to be written
|
// One more char to be written
|
||||||
uint16_t last;
|
uint16_t last;
|
||||||
if (nchars == max_chars - 1 &&
|
CHECK_EQ(str->Write(isolate, &last, nchars, 1, flags), 1);
|
||||||
str->Write(isolate, &last, nchars, 1, flags) != 0) {
|
|
||||||
memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
|
memcpy(buf + nchars * sizeof(*dst), &last, sizeof(last));
|
||||||
nchars++;
|
nchars++;
|
||||||
}
|
|
||||||
|
|
||||||
*chars_written = nchars;
|
*chars_written = nchars;
|
||||||
return nchars * sizeof(*dst);
|
return nchars * sizeof(*dst);
|
||||||
|
@ -91,3 +91,11 @@ assert.strictEqual(Buffer.compare(z, Buffer.alloc(4, 0)), 0);
|
|||||||
// Large overrun could corrupt the process
|
// Large overrun could corrupt the process
|
||||||
assert.strictEqual(Buffer.alloc(4)
|
assert.strictEqual(Buffer.alloc(4)
|
||||||
.write('ыыыыыы'.repeat(100), 3, 'utf16le'), 0);
|
.write('ыыыыыы'.repeat(100), 3, 'utf16le'), 0);
|
||||||
|
|
||||||
|
{
|
||||||
|
// .write() does not affect the byte after the written-to slice of the Buffer.
|
||||||
|
// Refs: https://github.com/nodejs/node/issues/26422
|
||||||
|
const buf = Buffer.alloc(8);
|
||||||
|
assert.strictEqual(buf.write('ыы', 1, 'utf16le'), 4);
|
||||||
|
assert.deepStrictEqual([...buf], [0, 0x4b, 0x04, 0x4b, 0x04, 0, 0, 0]);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user