From b0e6a6b3d5b1ab3a1c2a7ac74f2e7ba17e1a20d3 Mon Sep 17 00:00:00 2001 From: zhenweijin Date: Tue, 26 Mar 2024 13:50:33 +0800 Subject: [PATCH] string_decoder: throw an error when writing a too long buffer PR-URL: https://github.com/nodejs/node/pull/52215 Fixes: https://github.com/nodejs/node/issues/52214 Reviewed-By: Anna Henningsen Reviewed-By: theanarkh Reviewed-By: Luigi Pinca Reviewed-By: James M Snell --- src/string_decoder.cc | 10 +++---- .../test-string-decoder-large-buffer.js | 29 +++++++++++++++++++ 2 files changed, 34 insertions(+), 5 deletions(-) create mode 100644 test/pummel/test-string-decoder-large-buffer.js diff --git a/src/string_decoder.cc b/src/string_decoder.cc index 203445f9381159..4c30c1119f1bd8 100644 --- a/src/string_decoder.cc +++ b/src/string_decoder.cc @@ -31,11 +31,11 @@ MaybeLocal MakeString(Isolate* isolate, Local error; MaybeLocal ret; if (encoding == UTF8) { - MaybeLocal utf8_string = String::NewFromUtf8( - isolate, - data, - v8::NewStringType::kNormal, - length); + MaybeLocal utf8_string; + if (length <= static_cast(v8::String::kMaxLength)) { + utf8_string = String::NewFromUtf8( + isolate, data, v8::NewStringType::kNormal, length); + } if (utf8_string.IsEmpty()) { isolate->ThrowException(node::ERR_STRING_TOO_LONG(isolate)); return MaybeLocal(); diff --git a/test/pummel/test-string-decoder-large-buffer.js b/test/pummel/test-string-decoder-large-buffer.js new file mode 100644 index 00000000000000..e72dfb58b61de4 --- /dev/null +++ b/test/pummel/test-string-decoder-large-buffer.js @@ -0,0 +1,29 @@ +'use strict'; +const common = require('../common'); + +// Buffer with size > INT32_MAX +common.skipIf32Bits(); + +const assert = require('assert'); +const { StringDecoder } = require('node:string_decoder'); +const kStringMaxLength = require('buffer').constants.MAX_STRING_LENGTH; + +const size = 2 ** 31; + +const stringTooLongError = { + message: `Cannot create a string longer than 0x${kStringMaxLength.toString(16)}` + + ' characters', + code: 'ERR_STRING_TOO_LONG', + name: 'Error', +}; + +try { + const buf = Buffer.allocUnsafe(size); + const decoder = new StringDecoder('utf8'); + assert.throws(() => decoder.write(buf), stringTooLongError); +} catch (e) { + if (e.code !== 'ERR_MEMORY_ALLOCATION_FAILED') { + throw e; + } + common.skip('insufficient space for Buffer.alloc'); +}