mirror of
https://github.com/denoland/deno.git
synced 2025-01-11 08:33:43 -05:00
fix(node): supported arguments to randomFillSync
(#20637)
Fixes https://github.com/denoland/deno/issues/20634
This commit is contained in:
parent
365d1ac7c2
commit
75a724890d
6 changed files with 111 additions and 99 deletions
|
@ -1,5 +1,11 @@
|
|||
// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license.
|
||||
import { createHash, createHmac, getHashes, randomUUID } from "node:crypto";
|
||||
import {
|
||||
createHash,
|
||||
createHmac,
|
||||
getHashes,
|
||||
randomFillSync,
|
||||
randomUUID,
|
||||
} from "node:crypto";
|
||||
import { Buffer } from "node:buffer";
|
||||
import { Readable } from "node:stream";
|
||||
import {
|
||||
|
@ -124,3 +130,13 @@ Deno.test("[node/crypto.getRandomUUID] works the same way as Web Crypto API", ()
|
|||
assertEquals(randomUUID().length, crypto.randomUUID().length);
|
||||
assertEquals(typeof randomUUID(), typeof crypto.randomUUID());
|
||||
});
|
||||
|
||||
Deno.test("[node/crypto.randomFillSync] supported arguments", () => {
|
||||
const buf = new Uint8Array(10);
|
||||
|
||||
assert(randomFillSync(buf));
|
||||
assert(randomFillSync(buf, 0));
|
||||
// @ts-ignore: arraybuffer arguments are valid.
|
||||
assert(randomFillSync(buf.buffer));
|
||||
assert(randomFillSync(new DataView(buf.buffer)));
|
||||
});
|
||||
|
|
|
@ -388,7 +388,7 @@ deno_core::extension!(deno_node,
|
|||
"internal/constants.ts",
|
||||
"internal/crypto/_keys.ts",
|
||||
"internal/crypto/_randomBytes.ts",
|
||||
"internal/crypto/_randomFill.ts",
|
||||
"internal/crypto/_randomFill.mjs",
|
||||
"internal/crypto/_randomInt.ts",
|
||||
"internal/crypto/certificate.ts",
|
||||
"internal/crypto/cipher.ts",
|
||||
|
|
90
ext/node/polyfills/internal/crypto/_randomFill.mjs
Normal file
90
ext/node/polyfills/internal/crypto/_randomFill.mjs
Normal file
|
@ -0,0 +1,90 @@
|
|||
// 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 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);
|
||||
|
||||
core.opAsync("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;
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
// 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";
|
||||
const { core } = globalThis.__bootstrap;
|
||||
const { ops } = core;
|
||||
|
||||
const kBufferMaxLength = 0x7fffffff;
|
||||
|
||||
function assertOffset(offset: number, length: number) {
|
||||
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: number, offset: number, length: number) {
|
||||
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: Buffer,
|
||||
cb: (err: Error | null, buf: Buffer) => void,
|
||||
): void;
|
||||
|
||||
export default function randomFill(
|
||||
buf: Buffer,
|
||||
offset: number,
|
||||
cb: (err: Error | null, buf: Buffer) => void,
|
||||
): void;
|
||||
|
||||
export default function randomFill(
|
||||
buf: Buffer,
|
||||
offset: number,
|
||||
size: number,
|
||||
cb: (err: Error | null, buf: Buffer) => void,
|
||||
): void;
|
||||
|
||||
export default function randomFill(
|
||||
buf: Buffer,
|
||||
offset?: number | ((err: Error | null, buf: Buffer) => void),
|
||||
size?: number | ((err: Error | null, buf: Buffer) => void),
|
||||
cb?: (err: Error | null, buf: Buffer) => void,
|
||||
) {
|
||||
if (typeof offset === "function") {
|
||||
cb = offset;
|
||||
offset = 0;
|
||||
size = buf.length;
|
||||
} else if (typeof size === "function") {
|
||||
cb = size;
|
||||
size = buf.length - Number(offset as number);
|
||||
}
|
||||
|
||||
assertOffset(offset as number, buf.length);
|
||||
assertSize(size as number, offset as number, buf.length);
|
||||
|
||||
core.opAsync("op_node_generate_secret_async", Math.floor(size as number))
|
||||
.then(
|
||||
(randomData: Uint8Array) => {
|
||||
const randomBuf = Buffer.from(randomData.buffer);
|
||||
randomBuf.copy(buf, offset as number, 0, size as number);
|
||||
cb!(null, buf);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
export function randomFillSync(buf: Buffer, offset = 0, size?: number) {
|
||||
assertOffset(offset, buf.length);
|
||||
|
||||
if (size === undefined) size = buf.length - offset;
|
||||
|
||||
assertSize(size, offset, buf.length);
|
||||
|
||||
const bytes: Uint8Array = new Uint8Array(Math.floor(size));
|
||||
ops.op_node_generate_secret(bytes);
|
||||
const bytesBuf: Buffer = Buffer.from(bytes.buffer);
|
||||
bytesBuf.copy(buf, offset, 0, size);
|
||||
|
||||
return buf;
|
||||
}
|
|
@ -8,7 +8,7 @@ import { notImplemented } from "ext:deno_node/_utils.ts";
|
|||
import randomBytes from "ext:deno_node/internal/crypto/_randomBytes.ts";
|
||||
import randomFill, {
|
||||
randomFillSync,
|
||||
} from "ext:deno_node/internal/crypto/_randomFill.ts";
|
||||
} from "ext:deno_node/internal/crypto/_randomFill.mjs";
|
||||
import randomInt from "ext:deno_node/internal/crypto/_randomInt.ts";
|
||||
import {
|
||||
validateBoolean,
|
||||
|
@ -29,7 +29,7 @@ export { default as randomBytes } from "ext:deno_node/internal/crypto/_randomByt
|
|||
export {
|
||||
default as randomFill,
|
||||
randomFillSync,
|
||||
} from "ext:deno_node/internal/crypto/_randomFill.ts";
|
||||
} from "ext:deno_node/internal/crypto/_randomFill.mjs";
|
||||
export { default as randomInt } from "ext:deno_node/internal/crypto/_randomInt.ts";
|
||||
|
||||
const primordials = globalThis.__bootstrap.primordials;
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
"ext:deno_node/internal/constants.ts": "../ext/node/polyfills/internal/constants.ts",
|
||||
"ext:deno_node/internal/crypto/_keys.ts": "../ext/node/polyfills/internal/crypto/_keys.ts",
|
||||
"ext:deno_node/internal/crypto/_randomBytes.ts": "../ext/node/polyfills/internal/crypto/_randomBytes.ts",
|
||||
"ext:deno_node/internal/crypto/_randomFill.ts": "../ext/node/polyfills/internal/crypto/_randomFill.ts",
|
||||
"ext:deno_node/internal/crypto/_randomFill.mjs": "../ext/node/polyfills/internal/crypto/_randomFill.mjs",
|
||||
"ext:deno_node/internal/crypto/_randomInt.ts": "../ext/node/polyfills/internal/crypto/_randomInt.ts",
|
||||
"ext:deno_node/internal/crypto/certificate.ts": "../ext/node/polyfills/internal/crypto/certificate.ts",
|
||||
"ext:deno_node/internal/crypto/cipher.ts": "../ext/node/polyfills/internal/crypto/cipher.ts",
|
||||
|
|
Loading…
Reference in a new issue