Skip to content

Commit bb48d92

Browse files
committed
src: clamp WriteUtf8 capacity to INT_MAX in EncodeInto
Signed-off-by: semimikoh <ejffjeosms@gmail.com>
1 parent a36efd4 commit bb48d92

File tree

3 files changed

+43
-49
lines changed

3 files changed

+43
-49
lines changed

src/encoding_binding.cc

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "string_bytes.h"
99
#include "v8.h"
1010

11+
#include <algorithm>
1112
#include <climits>
1213
#include <cstdint>
1314

@@ -98,14 +99,12 @@ void BindingData::EncodeInto(const FunctionCallbackInfo<Value>& args) {
9899
Local<ArrayBuffer> buf = dest->Buffer();
99100
char* write_result = static_cast<char*>(buf->Data()) + dest->ByteOffset();
100101
size_t dest_length = dest->ByteLength();
101-
int max_length =
102-
dest_length > static_cast<size_t>(INT_MAX) ? INT_MAX : dest_length;
103102

104103
int nchars;
105104
int written = source->WriteUtf8(
106105
isolate,
107106
write_result,
108-
max_length,
107+
std::min(dest_length, static_cast<size_t>(INT_MAX)),
109108
&nchars,
110109
String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8);
111110

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
5+
common.skipIf32Bits();
6+
7+
const assert = require('assert');
8+
9+
const encoder = new TextEncoder();
10+
const source = 'a\xFF\u6211\u{1D452}';
11+
const expected = encoder.encode(source);
12+
13+
const size = 2 ** 31 + expected.length;
14+
const offset = expected.length - 1;
15+
let dest;
16+
17+
try {
18+
dest = new Uint8Array(size);
19+
} catch (e) {
20+
if (e.code === 'ERR_MEMORY_ALLOCATION_FAILED' ||
21+
/Array buffer allocation failed/.test(e.message)) {
22+
common.skip('insufficient space for Uint8Array allocation');
23+
}
24+
throw e;
25+
}
26+
27+
const large = encoder.encodeInto(source, dest.subarray(offset));
28+
assert.deepStrictEqual(large, {
29+
read: source.length,
30+
written: expected.length,
31+
});
32+
assert.deepStrictEqual(dest.slice(offset, offset + expected.length), expected);
33+
34+
const bounded = encoder.encodeInto(source,
35+
dest.subarray(offset,
36+
offset + expected.length));
37+
assert.deepStrictEqual(bounded, {
38+
read: source.length,
39+
written: expected.length,
40+
});
41+
assert.deepStrictEqual(dest.slice(offset, offset + expected.length), expected);

test/pummel/test-whatwg-encoding-encodeinto-large.js

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)