FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

src: fix out-of-bounds write when transcoding odd-length ucs2 · nodejs/node@b405e9b · GitHub

/ node Public

Commit b405e9b

Browse files
authored andcommitted
src: fix out-of-bounds write when transcoding odd-length ucs2
Signed-off-by: Nashit-h <nashit@bugqore.com> PR-URL: #64512 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: René <contact.9a5d6388@renegade334.me.uk>
1 parent 98e6272 commit b405e9b

2 files changed

Lines changed: 20 additions & 2 deletions

File tree

‎src/node_i18n.cc‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,13 @@ MaybeLocal<Object> ToBufferEndian(Environment* env, MaybeStackBuffer<T>* buf) {
121121

122122
void CopySourceBuffer(MaybeStackBuffer<UChar>* dest,
123123
const char* data,
124-
const size_t length,
125124
const size_t length_in_chars) {
126125
dest->AllocateSufficientStorage(length_in_chars);
127126
char* dst = reinterpret_cast<char*>(**dest);
127+
// The destination holds length_in_chars UChar units. Copy that many whole
128+
// units and ignore a trailing odd byte; copying the raw byte length would
129+
// write one byte past the buffer when the source length is not even.
130+
const size_t length = length_in_chars * sizeof(UChar);
128131
memcpy(dst, data, length);
129132
if constexpr (IsBigEndian()) {
130133
CHECK(nbytes::SwapBytes16(dst, length));
@@ -197,7 +200,7 @@ MaybeLocal<Object> TranscodeFromUcs2(Environment* env,
197200
to.set_subst_chars(sub.c_str());
198201

199202
const size_t length_in_chars = source_length / sizeof(UChar);
200-
CopySourceBuffer(&sourcebuf, source, source_length, length_in_chars);
203+
CopySourceBuffer(&sourcebuf, source, length_in_chars);
201204
MaybeStackBuffer<char> destbuf(length_in_chars);
202205
const uint32_t len = ucnv_fromUChars(to.conv(), *destbuf, length_in_chars,
203206
*sourcebuf, length_in_chars, status);

‎test/parallel/test-icu-transcode.js‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,3 +88,18 @@ assert.deepStrictEqual(
8888
{
8989
buffer.transcode(new buffer.Buffer.allocUnsafeSlow(1), 'utf16le', 'ucs2');
9090
}
91+
92+
// An odd-length ucs2 source must only convert whole 2-byte code units and
93+
// leave the trailing byte untouched, without reading or writing past the
94+
// conversion buffer. Lengths are chosen to exercise both the on-stack and the
95+
// heap-allocated code paths.
96+
for (const len of [2049, 4099]) {
97+
const src = Buffer.alloc(len, 0x61);
98+
const wholeUnits = src.subarray(0, len - 1);
99+
for (const to of ['latin1', 'ascii']) {
100+
assert.deepStrictEqual(
101+
buffer.transcode(src, 'utf16le', to),
102+
buffer.transcode(wholeUnits, 'utf16le', to),
103+
`ucs2->${to} odd length ${len}`);
104+
}
105+
}

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL