mirror of
https://github.com/oven-sh/bun
synced 2026-02-12 11:59:00 +00:00
fix(randomInt) allow negatives and improve args validation (#13527)
This commit is contained in:
@@ -2912,6 +2912,15 @@ pub const JSGlobalObject = opaque {
|
||||
this.ERR_INVALID_ARG_TYPE("The \"{s}\" argument must be of type {s}. Received {}", .{ argname, typename, bun.fmt.quote(ty_str.slice()) }).throw();
|
||||
return .zero;
|
||||
}
|
||||
pub fn throwInvalidArgumentRangeValue(
|
||||
this: *JSGlobalObject,
|
||||
argname: []const u8,
|
||||
typename: []const u8,
|
||||
value: i64,
|
||||
) JSValue {
|
||||
this.ERR_OUT_OF_RANGE("The \"{s}\" is out of range. {s}. Received {}", .{ argname, typename, value }).throw();
|
||||
return .zero;
|
||||
}
|
||||
|
||||
pub fn createNotEnoughArguments(
|
||||
this: *JSGlobalObject,
|
||||
@@ -4422,7 +4431,7 @@ pub const JSValue = enum(JSValueReprInt) {
|
||||
}
|
||||
|
||||
pub fn jsNumberFromInt64(i: i64) JSValue {
|
||||
if (i <= std.math.maxInt(i32)) {
|
||||
if (i <= std.math.maxInt(i32) and i >= std.math.minInt(i32)) {
|
||||
return jsNumberFromInt32(@as(i32, @intCast(i)));
|
||||
}
|
||||
|
||||
|
||||
@@ -11,20 +11,32 @@ const assert = bun.assert;
|
||||
const EVP = Crypto.EVP;
|
||||
const PBKDF2 = EVP.PBKDF2;
|
||||
const JSValue = JSC.JSValue;
|
||||
|
||||
const validators = @import("./util/validators.zig");
|
||||
fn randomInt(globalThis: *JSC.JSGlobalObject, callframe: *JSC.CallFrame) JSC.JSValue {
|
||||
const arguments = callframe.arguments(2).slice();
|
||||
|
||||
var at_least: u52 = 0;
|
||||
var at_most: u52 = std.math.maxInt(u52);
|
||||
|
||||
//min, max
|
||||
if (!arguments[0].isNumber()) return globalThis.throwInvalidArgumentTypeValue("min", "safe integer", arguments[0]);
|
||||
if (!arguments[1].isNumber()) return globalThis.throwInvalidArgumentTypeValue("max", "safe integer", arguments[1]);
|
||||
at_least = arguments[0].to(u52);
|
||||
at_most = arguments[1].to(u52);
|
||||
const min = arguments[0].to(i64);
|
||||
const max = arguments[1].to(i64);
|
||||
|
||||
if(min > validators.NUMBER__MAX_SAFE_INTEGER or min < validators.NUMBER__MIN_SAFE_INTEGER) {
|
||||
return globalThis.throwInvalidArgumentRangeValue("min", "It must be a safe integer type number", min);
|
||||
}
|
||||
if(max > validators.NUMBER__MAX_SAFE_INTEGER) {
|
||||
return globalThis.throwInvalidArgumentRangeValue("max", "It must be a safe integer type number", max);
|
||||
}
|
||||
if(min >= max) {
|
||||
return globalThis.throwInvalidArgumentRangeValue("max", "should be greater than min", max);
|
||||
}
|
||||
const diff = max - min;
|
||||
if(diff > 281474976710655) {
|
||||
return globalThis.throwInvalidArgumentRangeValue("max - min", "It must be <= 281474976710655", diff);
|
||||
}
|
||||
|
||||
return JSC.JSValue.jsNumberFromUint64(std.crypto.random.intRangeLessThan(u52, at_least, at_most));
|
||||
return JSC.JSValue.jsNumberFromInt64(std.crypto.random.intRangeLessThan(i64, min, max));
|
||||
}
|
||||
|
||||
fn pbkdf2(
|
||||
|
||||
31
test/js/node/crypto/crypto-random.test.ts
Normal file
31
test/js/node/crypto/crypto-random.test.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { it, expect, describe } from "bun:test";
|
||||
import { randomInt } from "crypto";
|
||||
|
||||
describe("randomInt args validation", async () => {
|
||||
it("default min is 0 so max should be greater than 0", () => {
|
||||
expect(() => randomInt(-1)).toThrow(RangeError);
|
||||
expect(() => randomInt(0)).toThrow(RangeError);
|
||||
});
|
||||
it("max should be >= min", () => {
|
||||
expect(() => randomInt(1, 0)).toThrow(RangeError);
|
||||
expect(() => randomInt(10, 5)).toThrow(RangeError);
|
||||
});
|
||||
|
||||
it("we allow negative numbers", () => {
|
||||
expect(() => randomInt(-2, -1)).not.toThrow(RangeError);
|
||||
});
|
||||
|
||||
it("max/min should not be greater than Number.MAX_SAFE_INTEGER or less than Number.MIN_SAFE_INTEGER", () => {
|
||||
expect(() => randomInt(Number.MAX_SAFE_INTEGER + 1)).toThrow(RangeError);
|
||||
expect(() => randomInt(-Number.MAX_SAFE_INTEGER - 1, -Number.MAX_SAFE_INTEGER + 1)).toThrow(RangeError);
|
||||
});
|
||||
|
||||
it("max - min should be <= 281474976710655", () => {
|
||||
expect(() => randomInt(-2, Number.MAX_SAFE_INTEGER)).toThrow(RangeError);
|
||||
expect(() => randomInt(-Number.MAX_SAFE_INTEGER, Number.MAX_SAFE_INTEGER)).toThrow(RangeError);
|
||||
});
|
||||
|
||||
it("accept large negative numbers", () => {
|
||||
expect(() => randomInt(-Number.MAX_SAFE_INTEGER, -Number.MAX_SAFE_INTEGER + 1)).not.toThrow(RangeError);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user