Skip to content

Commit

Permalink
buffer: don't CHECK on zero-sized realloc
Browse files Browse the repository at this point in the history
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: #3496
PR-URL: #3499
Reviewed-By: Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
  • Loading branch information
bnoordhuis authored and rvagg committed Oct 26, 2015
1 parent cd83f7e commit 1a41feb
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 9 deletions.
30 changes: 21 additions & 9 deletions src/node_buffer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -211,18 +211,30 @@ MaybeLocal<Object> New(Isolate* isolate,
enum encoding enc) {
EscapableHandleScope scope(isolate);

size_t length = StringBytes::Size(isolate, string, enc);
char* data = static_cast<char*>(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<char*>(malloc(length));

if (data == nullptr)
return Local<Object>();
if (data == nullptr)
return Local<Object>();

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<char*>(realloc(data, actual));
CHECK_NE(data, nullptr);
if (actual == 0) {
free(data);
data = nullptr;
} else if (actual < length) {
data = static_cast<char*>(realloc(data, actual));
CHECK_NE(data, nullptr);
}
}

Local<Object> buf;
Expand Down
3 changes: 3 additions & 0 deletions test/parallel/test-buffer.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 = '';
Expand Down

0 comments on commit 1a41feb

Please sign in to comment.