Fix incorrect output issue with large numbers (and add a changelog). Closes #1.

master
Sven Slootweg 8 years ago
parent aabdb1fc5f
commit 33d58fb712

@ -61,3 +61,9 @@ Optionally also accepts a nodeback as `cb`, but seriously, you should be using [
Any errors that occur during the random number generation process will be of this type. The error object will also have a `code` property, set to the string `"RandomGenerationError"`.
The error message will provide more information, but this kind of error will generally mean that the arguments you've specified are somehow invalid.
## Changelog
* __1.0.2__ (March 8, 2016): __*Security release!*__ Patched handling of large numbers; input values are now checked for `MIN_SAFE_INTEGER` and `MAX_SAFE_INTEGER`, and the correct bitwise operator is used (`>>>` rather than `>>`).
* __1.0.1__ (March 8, 2016): Unimportant file cleanup.
* __1.0.0__ (March 8, 2016): Initial release.

@ -32,7 +32,15 @@ function calculateParameters(range) {
bitsNeeded += 1;
mask = mask << 1 | 1; /* 0x00001111 -> 0x00011111 */
range = range >> 1; /* 0x01000000 -> 0x00100000 */
/* SECURITY PATCH (March 8, 2016):
* As it turns out, `>>` is not the right operator to use here, and
* using it would cause strange outputs, that wouldn't fall into
* the specified range. This was remedied by switching to `>>>`
* instead, and adding checks for input parameters being within the
* range of 'safe integers' in JavaScript.
*/
range = range >>> 1; /* 0x01000000 -> 0x00100000 */
}
return { bitsNeeded: bitsNeeded, bytesNeeded: bytesNeeded, mask: mask };
@ -64,8 +72,28 @@ module.exports = function secureRandomNumber(minimum, maximum, cb) {
throw new RandomGenerationError("The maximum value must be higher than the minimum value.");
}
/* We hardcode the values for the following:
*
* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER
* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
*
* ... as Babel does not appear to transpile them, despite being ES6.
*/
if (minimum < -9007199254740991 || minimum > 9007199254740991) {
throw new RandomGenerationError("The minimum value must be inbetween MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.");
}
if (maximum < -9007199254740991 || maximum > 9007199254740991) {
throw new RandomGenerationError("The maximum value must be inbetween MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.");
}
var range = maximum - minimum;
if (range < -9007199254740991 || range > 9007199254740991) {
throw new RandomGenerationError("The range between the minimum and maximum value must be inbetween MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.");
}
var _calculateParameters = calculateParameters(range);
var bitsNeeded = _calculateParameters.bitsNeeded;
@ -73,10 +101,6 @@ module.exports = function secureRandomNumber(minimum, maximum, cb) {
var mask = _calculateParameters.mask;
if (bitsNeeded > 53) {
throw new RandomGenerationError("Cannot generate numbers larger than 53 bits.");
}
return Promise.try(function () {
return crypto.randomBytesAsync(bytesNeeded);
}).then(function (randomBytes) {

@ -32,7 +32,15 @@ function calculateParameters(range) {
bitsNeeded += 1;
mask = mask << 1 | 1; /* 0x00001111 -> 0x00011111 */
range = range >> 1; /* 0x01000000 -> 0x00100000 */
/* SECURITY PATCH (March 8, 2016):
* As it turns out, `>>` is not the right operator to use here, and
* using it would cause strange outputs, that wouldn't fall into
* the specified range. This was remedied by switching to `>>>`
* instead, and adding checks for input parameters being within the
* range of 'safe integers' in JavaScript.
*/
range = range >>> 1; /* 0x01000000 -> 0x00100000 */
}
return {bitsNeeded, bytesNeeded, mask};
@ -64,13 +72,30 @@ module.exports = function secureRandomNumber(minimum, maximum, cb) {
throw new RandomGenerationError("The maximum value must be higher than the minimum value.")
}
/* We hardcode the values for the following:
*
* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER
* https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
*
* ... as Babel does not appear to transpile them, despite being ES6.
*/
if (minimum < -9007199254740991 || minimum > 9007199254740991) {
throw new RandomGenerationError("The minimum value must be inbetween MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.");
}
if (maximum < -9007199254740991 || maximum > 9007199254740991) {
throw new RandomGenerationError("The maximum value must be inbetween MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.");
}
let range = maximum - minimum;
let {bitsNeeded, bytesNeeded, mask} = calculateParameters(range);
if (bitsNeeded > 53) {
throw new RandomGenerationError("Cannot generate numbers larger than 53 bits.");
if (range < -9007199254740991 || range > 9007199254740991) {
throw new RandomGenerationError("The range between the minimum and maximum value must be inbetween MIN_SAFE_INTEGER and MAX_SAFE_INTEGER.");
}
let {bitsNeeded, bytesNeeded, mask} = calculateParameters(range);
return Promise.try(() => {
return crypto.randomBytesAsync(bytesNeeded);
}).then((randomBytes) => {

Loading…
Cancel
Save