Skip to content

Commit 55adc25

Browse files
oyydtargos
authored andcommitted
lib: enable TypedArray and DataView for the v8 module
This commit allow passing `TypedArray` and `DataView` to: - v8.deserialize() - new v8.Deserializer() - v8.serializer.writeRawBytes() PR-URL: #23953 Refs: #1826 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Refael Ackermann <refack@gmail.com>
1 parent 063b40e commit 55adc25

File tree

3 files changed

+91
-7
lines changed

3 files changed

+91
-7
lines changed

doc/api/v8.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ Uses a [`DefaultSerializer`][] to serialize `value` into a buffer.
185185
added: v8.0.0
186186
-->
187187

188-
* `buffer` {Buffer|Uint8Array} A buffer returned by [`serialize()`][].
188+
* `buffer` {Buffer|TypedArray|DataView} A buffer returned by [`serialize()`][].
189189

190190
Uses a [`DefaultDeserializer`][] with default options to read a JS value
191191
from a buffer.
@@ -252,7 +252,7 @@ For use inside of a custom [`serializer._writeHostObject()`][].
252252

253253
#### serializer.writeRawBytes(buffer)
254254

255-
* `buffer` {Buffer|Uint8Array}
255+
* `buffer` {Buffer|TypedArray|DataView}
256256

257257
Write raw bytes into the serializer’s internal buffer. The deserializer
258258
will require a way to compute the length of the buffer.
@@ -308,7 +308,7 @@ added: v8.0.0
308308

309309
#### new Deserializer(buffer)
310310

311-
* `buffer` {Buffer|Uint8Array} A buffer returned by
311+
* `buffer` {Buffer|TypedArray|DataView} A buffer returned by
312312
[`serializer.releaseBuffer()`][].
313313

314314
Creates a new `Deserializer` object.

src/node_serdes.cc

+4-4
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,9 @@ void SerializerContext::WriteRawBytes(const FunctionCallbackInfo<Value>& args) {
266266
SerializerContext* ctx;
267267
ASSIGN_OR_RETURN_UNWRAP(&ctx, args.Holder());
268268

269-
if (!args[0]->IsUint8Array()) {
269+
if (!args[0]->IsArrayBufferView()) {
270270
return node::THROW_ERR_INVALID_ARG_TYPE(
271-
ctx->env(), "source must be a Uint8Array");
271+
ctx->env(), "source must be a TypedArray or a DataView");
272272
}
273273

274274
ctx->serializer_.WriteRawBytes(Buffer::Data(args[0]),
@@ -317,9 +317,9 @@ MaybeLocal<Object> DeserializerContext::ReadHostObject(Isolate* isolate) {
317317
void DeserializerContext::New(const FunctionCallbackInfo<Value>& args) {
318318
Environment* env = Environment::GetCurrent(args);
319319

320-
if (!args[0]->IsUint8Array()) {
320+
if (!args[0]->IsArrayBufferView()) {
321321
return node::THROW_ERR_INVALID_ARG_TYPE(
322-
env, "buffer must be a Uint8Array");
322+
env, "buffer must be a TypedArray or a DataView");
323323
}
324324

325325
new DeserializerContext(env, args.This(), args[0]);

test/parallel/test-v8-serdes.js

+84
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,47 @@ const deserializerTypeError =
9898
assert.strictEqual(des.readValue().val, hostObject);
9999
}
100100

101+
// This test ensures that `v8.Serializer.writeRawBytes()` support
102+
// `TypedArray` and `DataView`.
103+
{
104+
const text = 'hostObjectTag';
105+
const data = Buffer.from(text);
106+
const arrayBufferViews = common.getArrayBufferViews(data);
107+
108+
// `buf` is one of `TypedArray` or `DataView`.
109+
function testWriteRawBytes(buf) {
110+
let writeHostObjectCalled = false;
111+
const ser = new v8.DefaultSerializer();
112+
113+
ser._writeHostObject = common.mustCall((object) => {
114+
writeHostObjectCalled = true;
115+
ser.writeUint32(buf.byteLength);
116+
ser.writeRawBytes(buf);
117+
});
118+
119+
ser.writeHeader();
120+
ser.writeValue({ val: hostObject });
121+
122+
const des = new v8.DefaultDeserializer(ser.releaseBuffer());
123+
des._readHostObject = common.mustCall(() => {
124+
assert.strictEqual(writeHostObjectCalled, true);
125+
const length = des.readUint32();
126+
const buf = des.readRawBytes(length);
127+
assert.strictEqual(buf.toString(), text);
128+
129+
return hostObject;
130+
});
131+
132+
des.readHeader();
133+
134+
assert.strictEqual(des.readValue().val, hostObject);
135+
}
136+
137+
arrayBufferViews.forEach((buf) => {
138+
testWriteRawBytes(buf);
139+
});
140+
}
141+
101142
{
102143
const ser = new v8.DefaultSerializer();
103144
ser._writeHostObject = common.mustCall((object) => {
@@ -146,3 +187,46 @@ const deserializerTypeError =
146187
assert.throws(v8.Serializer, serializerTypeError);
147188
assert.throws(v8.Deserializer, deserializerTypeError);
148189
}
190+
191+
192+
// `v8.deserialize()` and `new v8.Deserializer()` should support both
193+
// `TypedArray` and `DataView`.
194+
{
195+
for (const obj of objects) {
196+
const buf = v8.serialize(obj);
197+
198+
for (const arrayBufferView of common.getArrayBufferViews(buf)) {
199+
assert.deepStrictEqual(v8.deserialize(arrayBufferView), obj);
200+
}
201+
202+
for (const arrayBufferView of common.getArrayBufferViews(buf)) {
203+
const deserializer = new v8.DefaultDeserializer(arrayBufferView);
204+
deserializer.readHeader();
205+
const value = deserializer.readValue();
206+
assert.deepStrictEqual(value, obj);
207+
208+
const serializer = new v8.DefaultSerializer();
209+
serializer.writeHeader();
210+
serializer.writeValue(value);
211+
assert.deepStrictEqual(buf, serializer.releaseBuffer());
212+
}
213+
}
214+
}
215+
216+
{
217+
const INVALID_SOURCE = 'INVALID_SOURCE_TYPE';
218+
const serializer = new v8.Serializer();
219+
serializer.writeHeader();
220+
assert.throws(
221+
() => serializer.writeRawBytes(INVALID_SOURCE),
222+
/^TypeError: source must be a TypedArray or a DataView$/,
223+
);
224+
assert.throws(
225+
() => v8.deserialize(INVALID_SOURCE),
226+
/^TypeError: buffer must be a TypedArray or a DataView$/,
227+
);
228+
assert.throws(
229+
() => new v8.Deserializer(INVALID_SOURCE),
230+
/^TypeError: buffer must be a TypedArray or a DataView$/,
231+
);
232+
}

0 commit comments

Comments
 (0)