diff --git a/src/node_buffer.cc b/src/node_buffer.cc index 5b2186feb8c707..aec97f15e2c809 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -497,6 +497,7 @@ MaybeLocal New(Environment* env, if (length > kMaxLength) { Isolate* isolate(env->isolate()); isolate->ThrowException(ERR_BUFFER_TOO_LARGE(isolate)); + free(data); return Local(); } } diff --git a/test/pummel/test-v8-serialize-buffer-too-large.js b/test/pummel/test-v8-serialize-buffer-too-large.js new file mode 100755 index 00000000000000..3498b9b18ad6df --- /dev/null +++ b/test/pummel/test-v8-serialize-buffer-too-large.js @@ -0,0 +1,32 @@ +'use strict'; +const common = require('../common'); + +// On IBMi, the rss memory always returns zero +if (common.isIBMi) + common.skip('On IBMi, the rss memory always returns zero'); + +const v8 = require('v8'); +const { kMaxLength } = require('buffer'); + +const PADDING_STRING = 'a'.repeat(3000); + +const i = 22; +const toSerialize = {}; + +for (let j = 0; j < 2 ** i; j++) { + toSerialize[j] = PADDING_STRING; +} + +const assert = require('assert'); + +const rssBefore = process.memoryUsage.rss(); + +// Fail to serialize a few times. +const expectedError = { code: 'ERR_BUFFER_TOO_LARGE' }; +assert.throws(() => v8.serialize(toSerialize), expectedError); +assert.throws(() => v8.serialize(toSerialize), expectedError); +assert.throws(() => v8.serialize(toSerialize), expectedError); + +// Check that (at least some of) the memory got freed. +const rssAfter = process.memoryUsage.rss(); +assert(rssAfter - rssBefore <= 2 * kMaxLength);