Skip to content

Commit 1a41feb

Browse files
bnoordhuisrvagg
authored andcommitted
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: #3496 PR-URL: #3499 Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Trevor Norris <[email protected]>
1 parent cd83f7e commit 1a41feb

File tree

2 files changed

+24
-9
lines changed

2 files changed

+24
-9
lines changed

src/node_buffer.cc

+21-9
Original file line numberDiff line numberDiff line change
@@ -211,18 +211,30 @@ MaybeLocal<Object> New(Isolate* isolate,
211211
enum encoding enc) {
212212
EscapableHandleScope scope(isolate);
213213

214-
size_t length = StringBytes::Size(isolate, string, enc);
215-
char* data = static_cast<char*>(malloc(length));
214+
const size_t length = StringBytes::Size(isolate, string, enc);
215+
size_t actual = 0;
216+
char* data = nullptr;
217+
218+
// malloc(0) and realloc(ptr, 0) have implementation-defined behavior in
219+
// that the standard allows them to either return a unique pointer or a
220+
// nullptr for zero-sized allocation requests. Normalize by always using
221+
// a nullptr.
222+
if (length > 0) {
223+
data = static_cast<char*>(malloc(length));
216224

217-
if (data == nullptr)
218-
return Local<Object>();
225+
if (data == nullptr)
226+
return Local<Object>();
219227

220-
size_t actual = StringBytes::Write(isolate, data, length, string, enc);
221-
CHECK(actual <= length);
228+
actual = StringBytes::Write(isolate, data, length, string, enc);
229+
CHECK(actual <= length);
222230

223-
if (actual < length) {
224-
data = static_cast<char*>(realloc(data, actual));
225-
CHECK_NE(data, nullptr);
231+
if (actual == 0) {
232+
free(data);
233+
data = nullptr;
234+
} else if (actual < length) {
235+
data = static_cast<char*>(realloc(data, actual));
236+
CHECK_NE(data, nullptr);
237+
}
226238
}
227239

228240
Local<Object> buf;

test/parallel/test-buffer.js

+3
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,9 @@ for (var i = 0; i < segments.length; ++i) {
550550
}
551551
assert.equal(b.toString('binary', 0, pos), 'Madness?! This is node.js!');
552552

553+
// Regression test for https://github.com/nodejs/node/issues/3496.
554+
assert.equal(Buffer('=bad'.repeat(1e4), 'base64').length, 0);
555+
553556
// Creating buffers larger than pool size.
554557
var l = Buffer.poolSize + 5;
555558
var s = '';

0 commit comments

Comments
 (0)