diff --git a/doc/api/crypto.md b/doc/api/crypto.md index b73093c648a9..0806500113b5 100644 --- a/doc/api/crypto.md +++ b/doc/api/crypto.md @@ -5574,9 +5574,12 @@ changes: * `buffer` {ArrayBuffer|Buffer|TypedArray|DataView} Must be supplied. The size of the provided `buffer` must not be larger than `2**31 - 1`. -* `offset` {number} **Default:** `0` -* `size` {number} **Default:** `buffer.length - offset`. The `size` must - not be larger than `2**31 - 1`. +* `offset` {number} The start position, in elements for a `TypedArray` and in + bytes for an `ArrayBuffer` or `DataView`. **Default:** `0` +* `size` {number} The amount to fill, in the same units as `offset`. + **Default:** `buffer.length - offset` for a `TypedArray`, or + `buffer.byteLength - offset` for an `ArrayBuffer` or `DataView`. The `size` + must not be larger than `2**31 - 1`. * `callback` {Function} `function(err, buf) {}`. This function is similar to [`crypto.randomBytes()`][] but requires the first @@ -5711,9 +5714,12 @@ changes: * `buffer` {ArrayBuffer|Buffer|TypedArray|DataView} Must be supplied. The size of the provided `buffer` must not be larger than `2**31 - 1`. -* `offset` {number} **Default:** `0` -* `size` {number} **Default:** `buffer.length - offset`. The `size` must - not be larger than `2**31 - 1`. +* `offset` {number} The start position, in elements for a `TypedArray` and in + bytes for an `ArrayBuffer` or `DataView`. **Default:** `0` +* `size` {number} The amount to fill, in the same units as `offset`. + **Default:** `buffer.length - offset` for a `TypedArray`, or + `buffer.byteLength - offset` for an `ArrayBuffer` or `DataView`. The `size` + must not be larger than `2**31 - 1`. * Returns: {ArrayBuffer|Buffer|TypedArray|DataView} The object passed as `buffer` argument. diff --git a/lib/internal/crypto/random.js b/lib/internal/crypto/random.js index a75c14fd2a1c..919ad68f5617 100644 --- a/lib/internal/crypto/random.js +++ b/lib/internal/crypto/random.js @@ -168,7 +168,7 @@ function randomFill(buf, offset, size, callback) { size = buf.length; } else if (typeof size === 'function') { callback = size; - size = buf.length - offset; + size = (buf.length ?? buf.byteLength) - offset; } else { validateFunction(callback, 'callback'); } diff --git a/test/parallel/test-crypto-random.js b/test/parallel/test-crypto-random.js index ceaa859a0e03..88b6fcba84d7 100644 --- a/test/parallel/test-crypto-random.js +++ b/test/parallel/test-crypto-random.js @@ -218,6 +218,55 @@ common.expectWarning('DeprecationWarning', })); } +{ + const buf = new Uint16Array(10); + const before = Buffer.from(buf.buffer).toString('hex'); + crypto.randomFillSync(buf, 1, 8); + const after = Buffer.from(buf.buffer).toString('hex'); + assert.notStrictEqual(before, after); + assert.deepStrictEqual(before.slice(0, 4), after.slice(0, 4)); + assert.deepStrictEqual(before.slice(-4), after.slice(-4)); +} + +{ + const buf = new Uint32Array(10); + const before = Buffer.from(buf.buffer).toString('hex'); + crypto.randomFillSync(buf, 1, 8); + const after = Buffer.from(buf.buffer).toString('hex'); + assert.notStrictEqual(before, after); + assert.deepStrictEqual(before.slice(0, 8), after.slice(0, 8)); + assert.deepStrictEqual(before.slice(-8), after.slice(-8)); +} + +{ + const buf = new Uint16Array(10); + const before = Buffer.from(buf.buffer).toString('hex'); + crypto.randomFill(buf, 1, 8, common.mustSucceed((buf) => { + const after = Buffer.from(buf.buffer).toString('hex'); + assert.notStrictEqual(before, after); + assert.deepStrictEqual(before.slice(0, 4), after.slice(0, 4)); + assert.deepStrictEqual(before.slice(-4), after.slice(-4)); + })); +} + +{ + const buf = new Uint32Array(10); + const before = Buffer.from(buf.buffer).toString('hex'); + crypto.randomFill(buf, 1, 8, common.mustSucceed((buf) => { + const after = Buffer.from(buf.buffer).toString('hex'); + assert.notStrictEqual(before, after); + assert.deepStrictEqual(before.slice(0, 8), after.slice(0, 8)); + assert.deepStrictEqual(before.slice(-8), after.slice(-8)); + })); +} + +{ + // randomFill() with an offset and no size must not throw for types + // without a .length property, matching randomFillSync(). + crypto.randomFill(new ArrayBuffer(10), 2, common.mustSucceed()); + crypto.randomFill(new DataView(new ArrayBuffer(10)), 2, common.mustSucceed()); +} + { [ Buffer.alloc(10),