// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. // TODO(petamoriken): enable prefer-primordials for node polyfills // deno-lint-ignore-file prefer-primordials import { MAX_SIZE as kMaxUint32, } from "ext:deno_node/internal/crypto/_randomBytes.ts"; import { Buffer } from "node:buffer"; import { isAnyArrayBuffer, isArrayBufferView } from "node:util/types"; import { ERR_INVALID_ARG_TYPE } from "ext:deno_node/internal/errors.ts"; const { core } = globalThis.__bootstrap; const { ops } = core; const { op_node_generate_secret_async, } = core.ensureFastOps(); const kBufferMaxLength = 0x7fffffff; function assertOffset(offset, length) { if (offset > kMaxUint32 || offset < 0) { throw new TypeError("offset must be a uint32"); } if (offset > kBufferMaxLength || offset > length) { throw new RangeError("offset out of range"); } } function assertSize(size, offset, length) { if (size > kMaxUint32 || size < 0) { throw new TypeError("size must be a uint32"); } if (size + offset > length || size > kBufferMaxLength) { throw new RangeError("buffer too small"); } } export default function randomFill( buf, offset, size, cb, ) { if (typeof offset === "function") { cb = offset; offset = 0; size = buf.length; } else if (typeof size === "function") { cb = size; size = buf.length - Number(offset); } assertOffset(offset, buf.length); assertSize(size, offset, buf.length); op_node_generate_secret_async(Math.floor(size)) .then( (randomData) => { const randomBuf = Buffer.from(randomData.buffer); randomBuf.copy(buf, offset, 0, size); cb(null, buf); }, ); } export function randomFillSync(buf, offset = 0, size) { if (!isAnyArrayBuffer(buf) && !isArrayBufferView(buf)) { throw new ERR_INVALID_ARG_TYPE( "buf", ["ArrayBuffer", "ArrayBufferView"], buf, ); } assertOffset(offset, buf.byteLength); if (size === undefined) { size = buf.byteLength - offset; } else { assertSize(size, offset, buf.byteLength); } if (size === 0) { return buf; } const bytes = new Uint8Array(buf.buffer ? buf.buffer : buf, offset, size); ops.op_node_generate_secret(bytes); return buf; }