Browse Source

src: Malloc/Calloc size 0 returns non-null pointer

Change `Malloc()/Calloc()` so that size zero does not return a null
pointer, consistent with prior behavior.

Fixes: https://github.com/nodejs/node/issues/8571
PR-URL: https://github.com/nodejs/node/pull/8572
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@keybase.io>
Reviewed-By: Yorkie Liu <yorkiefixer@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
v6
Rich Trott 8 years ago
parent
commit
d2eb7ce010
  1. 2
      src/node_crypto.cc
  2. 4
      src/util-inl.h
  3. 14
      test/cctest/util.cc
  4. 8
      test/parallel/test-crypto-pbkdf2.js

2
src/node_crypto.cc

@ -5368,7 +5368,7 @@ class RandomBytesRequest : public AsyncWrap {
error_(0), error_(0),
size_(size), size_(size),
data_(static_cast<char*>(node::Malloc(size))) { data_(static_cast<char*>(node::Malloc(size))) {
if (data() == nullptr && size > 0) if (data() == nullptr)
FatalError("node::RandomBytesRequest()", "Out of Memory"); FatalError("node::RandomBytesRequest()", "Out of Memory");
Wrap(object, this); Wrap(object, this);
} }

4
src/util-inl.h

@ -246,11 +246,13 @@ void* Realloc(void* pointer, size_t size) {
// As per spec realloc behaves like malloc if passed nullptr. // As per spec realloc behaves like malloc if passed nullptr.
void* Malloc(size_t size) { void* Malloc(size_t size) {
if (size == 0) size = 1;
return Realloc(nullptr, size); return Realloc(nullptr, size);
} }
void* Calloc(size_t n, size_t size) { void* Calloc(size_t n, size_t size) {
if ((n == 0) || (size == 0)) return nullptr; if (n == 0) n = 1;
if (size == 0) size = 1;
CHECK_GE(n * size, n); // Overflow guard. CHECK_GE(n * size, n); // Overflow guard.
return calloc(n, size); return calloc(n, size);
} }

14
test/cctest/util.cc

@ -89,3 +89,17 @@ TEST(UtilTest, ToLower) {
EXPECT_EQ('a', ToLower('a')); EXPECT_EQ('a', ToLower('a'));
EXPECT_EQ('a', ToLower('A')); EXPECT_EQ('a', ToLower('A'));
} }
TEST(UtilTest, Malloc) {
using node::Malloc;
EXPECT_NE(nullptr, Malloc(0));
EXPECT_NE(nullptr, Malloc(1));
}
TEST(UtilTest, Calloc) {
using node::Calloc;
EXPECT_NE(nullptr, Calloc(0, 0));
EXPECT_NE(nullptr, Calloc(1, 0));
EXPECT_NE(nullptr, Calloc(0, 1));
EXPECT_NE(nullptr, Calloc(1, 1));
}

8
test/parallel/test-crypto-pbkdf2.js

@ -84,3 +84,11 @@ assert.throws(function() {
assert.throws(function() { assert.throws(function() {
crypto.pbkdf2('password', 'salt', 1, 4073741824, 'sha256', common.fail); crypto.pbkdf2('password', 'salt', 1, 4073741824, 'sha256', common.fail);
}, /Bad key length/); }, /Bad key length/);
// Should not get FATAL ERROR with empty password and salt
// https://github.com/nodejs/node/issues/8571
assert.doesNotThrow(() => {
crypto.pbkdf2('', '', 1, 32, 'sha256', common.mustCall((e) => {
assert.ifError(e);
}));
});

Loading…
Cancel
Save