From 1a41feb559bd907ca0640b979909cdb0448c3064 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Fri, 23 Oct 2015 19:10:49 +0200 Subject: [PATCH] buffer: don't CHECK on zero-sized realloc malloc(0) and realloc(ptr, 0) have implementation-defined behavior in that the standard allows them to either return a unique pointer or a nullptr for zero-sized allocation requests. Normalize by always using a nullptr. Fixes: https://github.com/nodejs/node/issues/3496 PR-URL: https://github.com/nodejs/node/pull/3499 Reviewed-By: Sakthipriyan Vairamani Reviewed-By: Trevor Norris --- src/node_buffer.cc | 30 +++++++++++++++++++++--------- test/parallel/test-buffer.js | 3 +++ 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/node_buffer.cc b/src/node_buffer.cc index a472d0c95e9225..7d428b2b134b51 100644 --- a/src/node_buffer.cc +++ b/src/node_buffer.cc @@ -211,18 +211,30 @@ MaybeLocal New(Isolate* isolate, enum encoding enc) { EscapableHandleScope scope(isolate); - size_t length = StringBytes::Size(isolate, string, enc); - char* data = static_cast(malloc(length)); + const size_t length = StringBytes::Size(isolate, string, enc); + size_t actual = 0; + char* data = nullptr; + + // malloc(0) and realloc(ptr, 0) have implementation-defined behavior in + // that the standard allows them to either return a unique pointer or a + // nullptr for zero-sized allocation requests. Normalize by always using + // a nullptr. + if (length > 0) { + data = static_cast(malloc(length)); - if (data == nullptr) - return Local(); + if (data == nullptr) + return Local(); - size_t actual = StringBytes::Write(isolate, data, length, string, enc); - CHECK(actual <= length); + actual = StringBytes::Write(isolate, data, length, string, enc); + CHECK(actual <= length); - if (actual < length) { - data = static_cast(realloc(data, actual)); - CHECK_NE(data, nullptr); + if (actual == 0) { + free(data); + data = nullptr; + } else if (actual < length) { + data = static_cast(realloc(data, actual)); + CHECK_NE(data, nullptr); + } } Local buf; diff --git a/test/parallel/test-buffer.js b/test/parallel/test-buffer.js index 1be4f3b8424352..37c9e6431e9c86 100644 --- a/test/parallel/test-buffer.js +++ b/test/parallel/test-buffer.js @@ -550,6 +550,9 @@ for (var i = 0; i < segments.length; ++i) { } assert.equal(b.toString('binary', 0, pos), 'Madness?! This is node.js!'); +// Regression test for https://github.com/nodejs/node/issues/3496. +assert.equal(Buffer('=bad'.repeat(1e4), 'base64').length, 0); + // Creating buffers larger than pool size. var l = Buffer.poolSize + 5; var s = '';