diff options
author | snek <the@snek.dev> | 2024-05-21 15:50:59 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-05-21 15:50:59 -0700 |
commit | 8f2d17140468512372ccd3aeebb0d505c607b977 (patch) | |
tree | b8a4e2d10a0cd3121d637e399b111b0c3dd8b32a /ext/node | |
parent | db82e8b557c9836481618a73cec7c014903ff256 (diff) |
feat(node): buffer isUtf8/isAscii (#23928)
Fixes: https://github.com/denoland/deno/issues/23657
Implements `isUtf8` and `isAscii` as ops.
Diffstat (limited to 'ext/node')
-rw-r--r-- | ext/node/lib.rs | 2 | ||||
-rw-r--r-- | ext/node/ops/buffer.rs | 13 | ||||
-rw-r--r-- | ext/node/ops/mod.rs | 1 | ||||
-rw-r--r-- | ext/node/polyfills/buffer.ts | 2 | ||||
-rw-r--r-- | ext/node/polyfills/internal/buffer.mjs | 49 | ||||
-rw-r--r-- | ext/node/polyfills/internal/errors.ts | 7 |
6 files changed, 74 insertions, 0 deletions
diff --git a/ext/node/lib.rs b/ext/node/lib.rs index b4eeb71c2..2b31f704f 100644 --- a/ext/node/lib.rs +++ b/ext/node/lib.rs @@ -186,6 +186,8 @@ deno_core::extension!(deno_node, deps = [ deno_io, deno_fs ], parameters = [P: NodePermissions], ops = [ + ops::buffer::op_is_ascii, + ops::buffer::op_is_utf8, ops::crypto::op_node_create_decipheriv, ops::crypto::op_node_cipheriv_encrypt, ops::crypto::op_node_cipheriv_final, diff --git a/ext/node/ops/buffer.rs b/ext/node/ops/buffer.rs new file mode 100644 index 000000000..74a011ab8 --- /dev/null +++ b/ext/node/ops/buffer.rs @@ -0,0 +1,13 @@ +// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. + +use deno_core::op2; + +#[op2(fast)] +pub fn op_is_ascii(#[buffer] buf: &[u8]) -> bool { + buf.is_ascii() +} + +#[op2(fast)] +pub fn op_is_utf8(#[buffer] buf: &[u8]) -> bool { + std::str::from_utf8(buf).is_ok() +} diff --git a/ext/node/ops/mod.rs b/ext/node/ops/mod.rs index 6381530dd..ae703e3f3 100644 --- a/ext/node/ops/mod.rs +++ b/ext/node/ops/mod.rs @@ -1,5 +1,6 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +pub mod buffer; pub mod crypto; pub mod fs; pub mod http; diff --git a/ext/node/polyfills/buffer.ts b/ext/node/polyfills/buffer.ts index 5925475c4..c5a910cb4 100644 --- a/ext/node/polyfills/buffer.ts +++ b/ext/node/polyfills/buffer.ts @@ -7,6 +7,8 @@ export { Buffer, constants, default, + isAscii, + isUtf8, kMaxLength, kStringMaxLength, SlowBuffer, diff --git a/ext/node/polyfills/internal/buffer.mjs b/ext/node/polyfills/internal/buffer.mjs index 5c76a21a5..0521c56aa 100644 --- a/ext/node/polyfills/internal/buffer.mjs +++ b/ext/node/polyfills/internal/buffer.mjs @@ -6,6 +6,7 @@ // deno-lint-ignore-file prefer-primordials import { core } from "ext:core/mod.js"; +import { op_is_ascii, op_is_utf8 } from "ext:core/ops"; import { TextDecoder, TextEncoder } from "ext:deno_web/08_text_encoding.js"; import { codes } from "ext:deno_node/internal/error_codes.ts"; @@ -26,10 +27,12 @@ import { import { isAnyArrayBuffer, isArrayBufferView, + isTypedArray, } from "ext:deno_node/internal/util/types.ts"; import { normalizeEncoding } from "ext:deno_node/internal/util.mjs"; import { validateBuffer } from "ext:deno_node/internal/validators.mjs"; import { isUint8Array } from "ext:deno_node/internal/util/types.ts"; +import { ERR_INVALID_STATE } from "ext:deno_node/internal/errors.ts"; import { forgivingBase64Encode, forgivingBase64UrlEncode, @@ -2536,12 +2539,58 @@ export function writeU_Int24LE(buf, value, offset, min, max) { return offset; } +export function isUtf8(input) { + if (isTypedArray(input)) { + if (input.buffer.detached) { + throw new ERR_INVALID_STATE("Cannot validate on a detached buffer"); + } + return op_is_utf8(input); + } + + if (isAnyArrayBuffer(input)) { + if (input.detached) { + throw new ERR_INVALID_STATE("Cannot validate on a detached buffer"); + } + return op_is_utf8(new Uint8Array(input)); + } + + throw new codes.ERR_INVALID_ARG_TYPE("input", [ + "ArrayBuffer", + "Buffer", + "TypedArray", + ], input); +} + +export function isAscii(input) { + if (isTypedArray(input)) { + if (input.buffer.detached) { + throw new ERR_INVALID_STATE("Cannot validate on a detached buffer"); + } + return op_is_ascii(input); + } + + if (isAnyArrayBuffer(input)) { + if (input.detached) { + throw new ERR_INVALID_STATE("Cannot validate on a detached buffer"); + } + return op_is_ascii(new Uint8Array(input)); + } + + throw new codes.ERR_INVALID_ARG_TYPE("input", [ + "ArrayBuffer", + "Buffer", + "TypedArray", + ], input); +} + export default { atob, btoa, Blob, Buffer, constants, + isAscii, + isUtf8, kMaxLength, kStringMaxLength, SlowBuffer, diff --git a/ext/node/polyfills/internal/errors.ts b/ext/node/polyfills/internal/errors.ts index c3aeff8b2..a16656087 100644 --- a/ext/node/polyfills/internal/errors.ts +++ b/ext/node/polyfills/internal/errors.ts @@ -2564,6 +2564,12 @@ export class ERR_HTTP_SOCKET_ASSIGNED extends NodeError { } } +export class ERR_INVALID_STATE extends NodeError { + constructor(message: string) { + super("ERR_INVALID_STATE", `Invalid state: ${message}`); + } +} + interface UvExceptionContext { syscall: string; path?: string; @@ -2824,6 +2830,7 @@ export default { ERR_INVALID_RETURN_PROPERTY, ERR_INVALID_RETURN_PROPERTY_VALUE, ERR_INVALID_RETURN_VALUE, + ERR_INVALID_STATE, ERR_INVALID_SYNC_FORK_INPUT, ERR_INVALID_THIS, ERR_INVALID_TUPLE, |