Commit b4165a35 authored by Camillo Bruni's avatar Camillo Bruni Committed by V8 LUCI CQ

[d8] Add ValueSerializer JS api for better fuzzing

Change-Id: Ib94979f4cf7f52a1544f2b3c0d51c0266a4fa14c
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3586985Reviewed-by: 's avatarMarja Hölttä <marja@chromium.org>
Commit-Queue: Camillo Bruni <cbruni@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80223}
parent 5647e654
......@@ -2281,6 +2281,50 @@ void Shell::SetPromiseHooks(const v8::FunctionCallbackInfo<v8::Value>& args) {
#endif // V8_ENABLE_JAVASCRIPT_PROMISE_HOOKS
}
void Shell::SerializerSerialize(
const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope handle_scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
ValueSerializer serializer(isolate);
serializer.WriteHeader();
for (int i = 0; i < args.Length(); i++) {
bool ok;
if (!serializer.WriteValue(context, args[i]).To(&ok)) return;
}
Local<v8::ArrayBuffer> buffer;
{
std::pair<uint8_t*, size_t> pair = serializer.Release();
buffer = ArrayBuffer::New(isolate, pair.second);
memcpy(buffer->GetBackingStore()->Data(), pair.first, pair.second);
free(pair.first);
}
args.GetReturnValue().Set(buffer);
}
void Shell::SerializerDeserialize(
const v8::FunctionCallbackInfo<v8::Value>& args) {
Isolate* isolate = args.GetIsolate();
HandleScope handle_scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
if (!args[0]->IsArrayBuffer()) {
isolate->ThrowError("Can only deserialize from an ArrayBuffer");
return;
}
std::shared_ptr<BackingStore> backing_store =
args[0].As<ArrayBuffer>()->GetBackingStore();
ValueDeserializer deserializer(
isolate, static_cast<const uint8_t*>(backing_store->Data()),
backing_store->ByteLength());
bool ok;
if (!deserializer.ReadHeader(context).To(&ok)) return;
Local<Value> result;
if (!deserializer.ReadValue(context).ToLocal(&result)) return;
args.GetReturnValue().Set(result);
}
void WriteToFile(FILE* file, const v8::FunctionCallbackInfo<v8::Value>& args) {
for (int i = 0; i < args.Length(); i++) {
HandleScope handle_scope(args.GetIsolate());
......@@ -3195,6 +3239,17 @@ Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
Local<Signature>(), 4));
d8_template->Set(isolate, "promise", promise_template);
}
{
Local<ObjectTemplate> serializer_template = ObjectTemplate::New(isolate);
serializer_template->Set(
isolate, "serialize",
FunctionTemplate::New(isolate, SerializerSerialize));
serializer_template->Set(
isolate, "deserialize",
FunctionTemplate::New(isolate, SerializerDeserialize, Local<Value>(),
Local<Signature>(), 1));
d8_template->Set(isolate, "serializer", serializer_template);
}
return d8_template;
}
......
......@@ -569,6 +569,11 @@ class Shell : public i::AllStatic {
static void SetPromiseHooks(const v8::FunctionCallbackInfo<v8::Value>& args);
static void SerializerSerialize(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void SerializerDeserialize(
const v8::FunctionCallbackInfo<v8::Value>& args);
static void Print(const v8::FunctionCallbackInfo<v8::Value>& args);
static void PrintErr(const v8::FunctionCallbackInfo<v8::Value>& args);
static void WriteStdout(const v8::FunctionCallbackInfo<v8::Value>& args);
......
// Copyright 2022 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Test the basic d8 value serializer interface
var largeArray = [];
largeArray[0xFFFF00] = 123;
let proto_obj = { fn1() { return 1 } }
let obj_with_enum_cache = {
__proto__: proto_obj,
a: 1,
b: 2,
c: "c"
};
for (let k in obj_with_enum_cache) {
// do something
obj_with_enum_cache.a += obj_with_enum_cache.fn1();
}
let string_1 = "aasdfasdfasdfasdf asd fa sdf asdf as dfa sdf asd f"
let string_2 = "aasdfasdfasdfasdf asd fa sdf UC16\u2028asdf as dfa sdf asd f"
var objects = [
true, false, null, undefined,
1, -1, 1.1, -2.2, -0, 0,
9007199254740991.0, 9007199254740991.0 + 10,
-9007199254740992.0, -9007199254740992.0 - 10,
Infinity, -Infinity, NaN,
string_1, string_1+"b", string_1.slice(1),
string_2, string_2+"b", string_2.slice(1),
{}, {1:1}, {a:1}, {1:1, 2:2}, Object.create(null),
obj_with_enum_cache,
[], [{}, {}], [1, 1, 1], [1.1, 1.1, 1.1, 1.1, 2], largeArray,
// new Proxy({},{}),
new Date(), new String(" a"),
new Uint8Array(12), new Float32Array([1, 2, 4, 5]),
new Uint8ClampedArray(2048),
/asdf/, new RegExp(),
new Map(), new Set(),
];
for (var o of objects) {
const serialised = d8.serializer.serialize(o)
const deserialised = d8.serializer.deserialize(serialised);
assertEquals(typeof deserialised, typeof o);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment