summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYagiz Nizipli <yagiz@nizipli.com>2023-01-19 22:24:40 -0500
committerGitHub <noreply@github.com>2023-01-20 03:24:40 +0000
commitbabe6d7c84b9cefe0b9bf9f1929d19c80cc30c7e (patch)
treef553aad2285989c02fa9aa890f1fe0d724db4295
parent49413ad8ae3c1c6c25caa60e150939c1cbb50094 (diff)
downloadnode-new-babe6d7c84b9cefe0b9bf9f1929d19c80cc30c7e.tar.gz
buffer: add isAscii method
PR-URL: https://github.com/nodejs/node/pull/46046 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
-rw-r--r--doc/api/buffer.md14
-rw-r--r--lib/buffer.js10
-rw-r--r--src/node_buffer.cc17
-rw-r--r--test/parallel/test-buffer-isascii.js42
4 files changed, 83 insertions, 0 deletions
diff --git a/doc/api/buffer.md b/doc/api/buffer.md
index 612f7a6718..28c1dbb945 100644
--- a/doc/api/buffer.md
+++ b/doc/api/buffer.md
@@ -5138,6 +5138,20 @@ For code running using Node.js APIs, converting between base64-encoded strings
and binary data should be performed using `Buffer.from(str, 'base64')` and
`buf.toString('base64')`.**
+### `buffer.isAscii(input)`
+
+<!-- YAML
+added: REPLACEME
+-->
+
+* input {Buffer | ArrayBuffer | TypedArray} The input to validate.
+* Returns: {boolean}
+
+This function returns `true` if `input` contains only valid ASCII-encoded data,
+including the case in which `input` is empty.
+
+Throws if the `input` is a detached array buffer.
+
### `buffer.isUtf8(input)`
<!-- YAML
diff --git a/lib/buffer.js b/lib/buffer.js
index 4fc6e57b1c..13654da10d 100644
--- a/lib/buffer.js
+++ b/lib/buffer.js
@@ -56,6 +56,7 @@ const {
compareOffset,
createFromString,
fill: bindingFill,
+ isAscii: bindingIsAscii,
isUtf8: bindingIsUtf8,
indexOfBuffer,
indexOfNumber,
@@ -1320,11 +1321,20 @@ function isUtf8(input) {
throw new ERR_INVALID_ARG_TYPE('input', ['TypedArray', 'Buffer'], input);
}
+function isAscii(input) {
+ if (isTypedArray(input) || isAnyArrayBuffer(input)) {
+ return bindingIsAscii(input);
+ }
+
+ throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input);
+}
+
module.exports = {
Buffer,
SlowBuffer,
transcode,
isUtf8,
+ isAscii,
// Legacy
kMaxLength,
diff --git a/src/node_buffer.cc b/src/node_buffer.cc
index f7b008af36..b144b95ab4 100644
--- a/src/node_buffer.cc
+++ b/src/node_buffer.cc
@@ -1238,6 +1238,21 @@ static void IsUtf8(const FunctionCallbackInfo<Value>& args) {
args.GetReturnValue().Set(simdutf::validate_utf8(abv.data(), abv.length()));
}
+static void IsAscii(const FunctionCallbackInfo<Value>& args) {
+ Environment* env = Environment::GetCurrent(args);
+ CHECK_EQ(args.Length(), 1);
+ CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() ||
+ args[0]->IsSharedArrayBuffer());
+ ArrayBufferViewContents<char> abv(args[0]);
+
+ if (abv.WasDetached()) {
+ return node::THROW_ERR_INVALID_STATE(
+ env, "Cannot validate on a detached buffer");
+ }
+
+ args.GetReturnValue().Set(simdutf::validate_ascii(abv.data(), abv.length()));
+}
+
void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) {
Environment* env = Environment::GetCurrent(args);
@@ -1373,6 +1388,7 @@ void Initialize(Local<Object> target,
SetMethodNoSideEffect(context, target, "encodeUtf8String", EncodeUtf8String);
SetMethodNoSideEffect(context, target, "isUtf8", IsUtf8);
+ SetMethodNoSideEffect(context, target, "isAscii", IsAscii);
target
->Set(context,
@@ -1430,6 +1446,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
registry->Register(EncodeUtf8String);
registry->Register(IsUtf8);
+ registry->Register(IsAscii);
registry->Register(StringSlice<ASCII>);
registry->Register(StringSlice<BASE64>);
diff --git a/test/parallel/test-buffer-isascii.js b/test/parallel/test-buffer-isascii.js
new file mode 100644
index 0000000000..b9468ca133
--- /dev/null
+++ b/test/parallel/test-buffer-isascii.js
@@ -0,0 +1,42 @@
+'use strict';
+
+require('../common');
+const assert = require('assert');
+const { isAscii, Buffer } = require('buffer');
+const { TextEncoder } = require('util');
+
+const encoder = new TextEncoder();
+
+assert.strictEqual(isAscii(encoder.encode('hello')), true);
+assert.strictEqual(isAscii(encoder.encode('ğ')), false);
+assert.strictEqual(isAscii(Buffer.from([])), true);
+
+[
+ undefined,
+ '', 'hello',
+ false, true,
+ 0, 1,
+ 0n, 1n,
+ Symbol(),
+ () => {},
+ {}, [], null,
+].forEach((input) => {
+ assert.throws(
+ () => { isAscii(input); },
+ {
+ code: 'ERR_INVALID_ARG_TYPE',
+ },
+ );
+});
+
+{
+ // Test with detached array buffers
+ const arrayBuffer = new ArrayBuffer(1024);
+ structuredClone(arrayBuffer, { transfer: [arrayBuffer] });
+ assert.throws(
+ () => { isAscii(arrayBuffer); },
+ {
+ code: 'ERR_INVALID_STATE'
+ }
+ );
+}