From 59c11c6d4c4755ebec56058c58915702429b1515 Mon Sep 17 00:00:00 2001 From: Benjamin Gruenbaum Date: Fri, 1 Sep 2017 16:08:40 +0300 Subject: [PATCH] crypto: accept decimal Number in randomBytes This change adds the ability to pass a double into randomBytes. PR-URL: https://github.com/nodejs/node/pull/15130 Fixes: https://github.com/nodejs/node/issues/15118 Reviewed-By: Sam Roberts --- src/node_crypto.cc | 6 +++--- test/parallel/test-crypto-random.js | 23 ++++++++++++----------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/node_crypto.cc b/src/node_crypto.cc index e6acb565d69ab1..3d3c53b4b8bad1 100644 --- a/src/node_crypto.cc +++ b/src/node_crypto.cc @@ -5616,13 +5616,13 @@ void RandomBytesProcessSync(Environment* env, void RandomBytes(const FunctionCallbackInfo& args) { Environment* env = Environment::GetCurrent(args); - if (!args[0]->IsUint32()) { + if (!args[0]->IsNumber() || args[0].As()->Value() < 0) { return env->ThrowTypeError("size must be a number >= 0"); } const int64_t size = args[0]->IntegerValue(); - if (size < 0 || size > Buffer::kMaxLength) - return env->ThrowRangeError("size is not a valid Smi"); + if (size > Buffer::kMaxLength) + return env->ThrowTypeError("size must be a uint32"); Local obj = env->randombytes_constructor_template()-> NewInstance(env->context()).ToLocalChecked(); diff --git a/test/parallel/test-crypto-random.js b/test/parallel/test-crypto-random.js index d9fa7efd9b6a4a..fb80e313abfeb3 100644 --- a/test/parallel/test-crypto-random.js +++ b/test/parallel/test-crypto-random.js @@ -33,6 +33,15 @@ crypto.DEFAULT_ENCODING = 'buffer'; // bump, we register a lot of exit listeners process.setMaxListeners(256); +const errMessages = { + offsetNotNumber: /^TypeError: offset must be a number$/, + offsetOutOfRange: /^RangeError: offset out of range$/, + offsetNotUInt32: /^TypeError: offset must be a uint32$/, + sizeNotNumber: /^TypeError: size must be a number$/, + sizeNotUInt32: /^TypeError: size must be a uint32$/, + bufferTooSmall: /^RangeError: buffer too small$/, +}; + const expectedErrorRegexp = /^TypeError: size must be a number >= 0$/; [crypto.randomBytes, crypto.pseudoRandomBytes].forEach(function(f) { [-1, undefined, null, false, true, {}, []].forEach(function(value) { @@ -41,10 +50,10 @@ const expectedErrorRegexp = /^TypeError: size must be a number >= 0$/; expectedErrorRegexp); }); - [0, 1, 2, 4, 16, 256, 1024].forEach(function(len) { + [0, 1, 2, 4, 16, 256, 1024, 101.2].forEach(function(len) { f(len, common.mustCall(function(ex, buf) { assert.strictEqual(ex, null); - assert.strictEqual(buf.length, len); + assert.strictEqual(buf.length, Math.floor(len)); assert.ok(Buffer.isBuffer(buf)); })); }); @@ -139,14 +148,6 @@ const expectedErrorRegexp = /^TypeError: size must be a number >= 0$/; Buffer.alloc(10), new Uint8Array(new Array(10).fill(0)) ]; - const errMessages = { - offsetNotNumber: /^TypeError: offset must be a number$/, - offsetOutOfRange: /^RangeError: offset out of range$/, - offsetNotUInt32: /^TypeError: offset must be a uint32$/, - sizeNotNumber: /^TypeError: size must be a number$/, - sizeNotUInt32: /^TypeError: size must be a uint32$/, - bufferTooSmall: /^RangeError: buffer too small$/, - }; const max = require('buffer').kMaxLength + 1; @@ -264,4 +265,4 @@ const expectedErrorRegexp = /^TypeError: size must be a number >= 0$/; // length exceeds max acceptable value" assert.throws(function() { crypto.randomBytes((-1 >>> 0) + 1); -}, /^TypeError: size must be a number >= 0$/); +}, errMessages.sizeNotUInt32);