2023-09-23 04:04:55 -04:00
|
|
|
// 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
|
|
|
|
|
2024-01-29 16:02:26 -05:00
|
|
|
import {
|
2024-01-10 17:37:25 -05:00
|
|
|
op_node_generate_secret,
|
|
|
|
op_node_generate_secret_async,
|
2024-01-29 16:02:26 -05:00
|
|
|
} from "ext:core/ops";
|
2024-01-10 17:37:25 -05:00
|
|
|
|
2023-09-23 04:04:55 -04:00
|
|
|
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 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);
|
|
|
|
|
2023-12-26 20:30:26 -05:00
|
|
|
op_node_generate_secret_async(Math.floor(size))
|
2023-09-23 04:04:55 -04:00
|
|
|
.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);
|
2024-01-10 17:37:25 -05:00
|
|
|
op_node_generate_secret(bytes);
|
2023-09-23 04:04:55 -04:00
|
|
|
|
|
|
|
return buf;
|
|
|
|
}
|