diff --git a/src/encoding_binding.cc b/src/encoding_binding.cc index cddc88f1e03090..5e0606352d3587 100644 --- a/src/encoding_binding.cc +++ b/src/encoding_binding.cc @@ -8,6 +8,8 @@ #include "string_bytes.h" #include "v8.h" +#include +#include #include namespace node { @@ -102,7 +104,7 @@ void BindingData::EncodeInto(const FunctionCallbackInfo& args) { int written = source->WriteUtf8( isolate, write_result, - dest_length, + std::min(dest_length, static_cast(INT_MAX)), &nchars, String::NO_NULL_TERMINATION | String::REPLACE_INVALID_UTF8); diff --git a/test/parallel/test-whatwg-encoding-encodeinto-large.js b/test/parallel/test-whatwg-encoding-encodeinto-large.js new file mode 100644 index 00000000000000..66360430675307 --- /dev/null +++ b/test/parallel/test-whatwg-encoding-encodeinto-large.js @@ -0,0 +1,41 @@ +'use strict'; + +const common = require('../common'); + +common.skipIf32Bits(); + +const assert = require('assert'); + +const encoder = new TextEncoder(); +const source = 'a\xFF\u6211\u{1D452}'; +const expected = encoder.encode(source); + +const size = 2 ** 31 + expected.length; +const offset = expected.length - 1; +let dest; + +try { + dest = new Uint8Array(size); +} catch (e) { + if (e.code === 'ERR_MEMORY_ALLOCATION_FAILED' || + /Array buffer allocation failed/.test(e.message)) { + common.skip('insufficient space for Uint8Array allocation'); + } + throw e; +} + +const large = encoder.encodeInto(source, dest.subarray(offset)); +assert.deepStrictEqual(large, { + read: source.length, + written: expected.length, +}); +assert.deepStrictEqual(dest.slice(offset, offset + expected.length), expected); + +const bounded = encoder.encodeInto(source, + dest.subarray(offset, + offset + expected.length)); +assert.deepStrictEqual(bounded, { + read: source.length, + written: expected.length, +}); +assert.deepStrictEqual(dest.slice(offset, offset + expected.length), expected);