Skip to content

Commit cb5bb12

Browse files
anonrigjuanarbol
authored andcommitted
buffer: add isAscii method
PR-URL: #46046 Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com> Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
1 parent 75b8db4 commit cb5bb12

File tree

4 files changed

+83
-0
lines changed

4 files changed

+83
-0
lines changed

doc/api/buffer.md

+14
Original file line numberDiff line numberDiff line change
@@ -5126,6 +5126,20 @@ For code running using Node.js APIs, converting between base64-encoded strings
51265126
and binary data should be performed using `Buffer.from(str, 'base64')` and
51275127
`buf.toString('base64')`.**
51285128

5129+
### `buffer.isAscii(input)`
5130+
5131+
<!-- YAML
5132+
added: REPLACEME
5133+
-->
5134+
5135+
* input {Buffer | ArrayBuffer | TypedArray} The input to validate.
5136+
* Returns: {boolean}
5137+
5138+
This function returns `true` if `input` contains only valid ASCII-encoded data,
5139+
including the case in which `input` is empty.
5140+
5141+
Throws if the `input` is a detached array buffer.
5142+
51295143
### `buffer.isUtf8(input)`
51305144

51315145
<!-- YAML

lib/buffer.js

+10
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ const {
5757
compareOffset,
5858
createFromString,
5959
fill: bindingFill,
60+
isAscii: bindingIsAscii,
6061
isUtf8: bindingIsUtf8,
6162
indexOfBuffer,
6263
indexOfNumber,
@@ -1332,6 +1333,14 @@ function isUtf8(input) {
13321333
throw new ERR_INVALID_ARG_TYPE('input', ['TypedArray', 'Buffer'], input);
13331334
}
13341335

1336+
function isAscii(input) {
1337+
if (isTypedArray(input) || isAnyArrayBuffer(input)) {
1338+
return bindingIsAscii(input);
1339+
}
1340+
1341+
throw new ERR_INVALID_ARG_TYPE('input', ['ArrayBuffer', 'Buffer', 'TypedArray'], input);
1342+
}
1343+
13351344
module.exports = {
13361345
Blob,
13371346
File,
@@ -1340,6 +1349,7 @@ module.exports = {
13401349
SlowBuffer,
13411350
transcode,
13421351
isUtf8,
1352+
isAscii,
13431353

13441354
// Legacy
13451355
kMaxLength,

src/node_buffer.cc

+17
Original file line numberDiff line numberDiff line change
@@ -1238,6 +1238,21 @@ static void IsUtf8(const FunctionCallbackInfo<Value>& args) {
12381238
args.GetReturnValue().Set(simdutf::validate_utf8(abv.data(), abv.length()));
12391239
}
12401240

1241+
static void IsAscii(const FunctionCallbackInfo<Value>& args) {
1242+
Environment* env = Environment::GetCurrent(args);
1243+
CHECK_EQ(args.Length(), 1);
1244+
CHECK(args[0]->IsTypedArray() || args[0]->IsArrayBuffer() ||
1245+
args[0]->IsSharedArrayBuffer());
1246+
ArrayBufferViewContents<char> abv(args[0]);
1247+
1248+
if (abv.WasDetached()) {
1249+
return node::THROW_ERR_INVALID_STATE(
1250+
env, "Cannot validate on a detached buffer");
1251+
}
1252+
1253+
args.GetReturnValue().Set(simdutf::validate_ascii(abv.data(), abv.length()));
1254+
}
1255+
12411256
void SetBufferPrototype(const FunctionCallbackInfo<Value>& args) {
12421257
Environment* env = Environment::GetCurrent(args);
12431258

@@ -1373,6 +1388,7 @@ void Initialize(Local<Object> target,
13731388
SetMethodNoSideEffect(context, target, "encodeUtf8String", EncodeUtf8String);
13741389

13751390
SetMethodNoSideEffect(context, target, "isUtf8", IsUtf8);
1391+
SetMethodNoSideEffect(context, target, "isAscii", IsAscii);
13761392

13771393
target
13781394
->Set(context,
@@ -1430,6 +1446,7 @@ void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
14301446
registry->Register(EncodeUtf8String);
14311447

14321448
registry->Register(IsUtf8);
1449+
registry->Register(IsAscii);
14331450

14341451
registry->Register(StringSlice<ASCII>);
14351452
registry->Register(StringSlice<BASE64>);

test/parallel/test-buffer-isascii.js

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
require('../common');
4+
const assert = require('assert');
5+
const { isAscii, Buffer } = require('buffer');
6+
const { TextEncoder } = require('util');
7+
8+
const encoder = new TextEncoder();
9+
10+
assert.strictEqual(isAscii(encoder.encode('hello')), true);
11+
assert.strictEqual(isAscii(encoder.encode('ğ')), false);
12+
assert.strictEqual(isAscii(Buffer.from([])), true);
13+
14+
[
15+
undefined,
16+
'', 'hello',
17+
false, true,
18+
0, 1,
19+
0n, 1n,
20+
Symbol(),
21+
() => {},
22+
{}, [], null,
23+
].forEach((input) => {
24+
assert.throws(
25+
() => { isAscii(input); },
26+
{
27+
code: 'ERR_INVALID_ARG_TYPE',
28+
},
29+
);
30+
});
31+
32+
{
33+
// Test with detached array buffers
34+
const arrayBuffer = new ArrayBuffer(1024);
35+
structuredClone(arrayBuffer, { transfer: [arrayBuffer] });
36+
assert.throws(
37+
() => { isAscii(arrayBuffer); },
38+
{
39+
code: 'ERR_INVALID_STATE'
40+
}
41+
);
42+
}

0 commit comments

Comments
 (0)