diff options
author | Anna Henningsen <anna@addaleax.net> | 2016-09-10 17:43:08 +0300 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2016-09-29 10:46:42 +0300 |
commit | eb927fac38a50252e11ebe0da1764e85294f95f0 (patch) | |
tree | 2c498902818f71c21f62361497ee608f7aa79be2 /src/util-inl.h | |
parent | 506cda6ea69e185bd27b1caec1d91c6b9041584c (diff) |
src: add Malloc() size param + overflow detection
Adds an optional second parameter to `node::Malloc()` and
an optional third parameter to `node::Realloc()` giving the
size/number of items to be allocated, in the style of `calloc(3)`.
Use a proper overflow check using division;
the previous `CHECK_GE(n * size, n);` would not detect all cases
of overflow (e.g. `size == SIZE_MAX / 2 && n == 3`).
PR-URL: https://github.com/nodejs/node/pull/8482
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Michael Dawson <michael_dawson@ca.ibm.com>
Reviewed-By: Ilkka Myller <ilkka.myller@nodefield.com>
Diffstat (limited to 'src/util-inl.h')
-rw-r--r-- | src/util-inl.h | 24 |
1 files changed, 18 insertions, 6 deletions
diff --git a/src/util-inl.h b/src/util-inl.h index 9357f675021..3f3139e1f05 100644 --- a/src/util-inl.h +++ b/src/util-inl.h @@ -229,6 +229,14 @@ bool StringEqualNoCaseN(const char* a, const char* b, size_t length) { return true; } +inline size_t MultiplyWithOverflowCheck(size_t a, size_t b) { + size_t ret = a * b; + if (a != 0) + CHECK_EQ(b, ret / a); + + return ret; +} + // These should be used in our code as opposed to the native // versions as they abstract out some platform and or // compiler version specific functionality. @@ -236,24 +244,28 @@ bool StringEqualNoCaseN(const char* a, const char* b, size_t length) { // 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. -void* Realloc(void* pointer, size_t size) { - if (size == 0) { +void* Realloc(void* pointer, size_t n, size_t size) { + size_t full_size = MultiplyWithOverflowCheck(size, n); + + if (full_size == 0) { free(pointer); return nullptr; } - return realloc(pointer, size); + + return realloc(pointer, full_size); } // As per spec realloc behaves like malloc if passed nullptr. -void* Malloc(size_t size) { +void* Malloc(size_t n, size_t size) { + if (n == 0) n = 1; if (size == 0) size = 1; - return Realloc(nullptr, size); + return Realloc(nullptr, n, size); } void* Calloc(size_t n, size_t size) { if (n == 0) n = 1; if (size == 0) size = 1; - CHECK_GE(n * size, n); // Overflow guard. + MultiplyWithOverflowCheck(size, n); return calloc(n, size); } |