Skip to content

Commit 43f41be

Browse files
oyydBethGriggs
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 <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: Refael Ackermann <[email protected]>
1 parent a1b253a commit 43f41be

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
@@ -95,6 +95,47 @@ const deserializerTypeError =
9595
assert.strictEqual(des.readValue().val, hostObject);
9696
}
9797

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

0 commit comments

Comments
 (0)