1 // Copyright 2016 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "src/objects/value-serializer.h"
6 
7 #include <algorithm>
8 #include <string>
9 
10 #include "include/v8-context.h"
11 #include "include/v8-date.h"
12 #include "include/v8-function.h"
13 #include "include/v8-json.h"
14 #include "include/v8-local-handle.h"
15 #include "include/v8-primitive-object.h"
16 #include "include/v8-template.h"
17 #include "include/v8-value-serializer.h"
18 #include "include/v8-wasm.h"
19 #include "src/api/api-inl.h"
20 #include "src/base/build_config.h"
21 #include "src/objects/backing-store.h"
22 #include "src/objects/objects-inl.h"
23 #include "test/unittests/test-utils.h"
24 #include "testing/gmock/include/gmock/gmock.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26 
27 #if V8_ENABLE_WEBASSEMBLY
28 #include "src/wasm/wasm-engine.h"
29 #include "src/wasm/wasm-objects.h"
30 #include "src/wasm/wasm-result.h"
31 #endif  // V8_ENABLE_WEBASSEMBLY
32 
33 namespace v8 {
34 namespace {
35 
36 using ::testing::_;
37 using ::testing::Invoke;
38 using ::testing::Return;
39 
40 class ValueSerializerTest : public TestWithIsolate {
41  public:
42   ValueSerializerTest(const ValueSerializerTest&) = delete;
43   ValueSerializerTest& operator=(const ValueSerializerTest&) = delete;
44 
45  protected:
ValueSerializerTest()46   ValueSerializerTest()
47       : serialization_context_(Context::New(isolate())),
48         deserialization_context_(Context::New(isolate())) {
49     // Create a host object type that can be tested through
50     // serialization/deserialization delegates below.
51     Local<FunctionTemplate> function_template = v8::FunctionTemplate::New(
52         isolate(), [](const FunctionCallbackInfo<Value>& args) {
53           args.Holder()->SetInternalField(0, args[0]);
54           args.Holder()->SetInternalField(1, args[1]);
55         });
56     function_template->InstanceTemplate()->SetInternalFieldCount(2);
57     function_template->InstanceTemplate()->SetAccessor(
58         StringFromUtf8("value"),
59         [](Local<String> property, const PropertyCallbackInfo<Value>& args) {
60           args.GetReturnValue().Set(args.Holder()->GetInternalField(0));
61         });
62     function_template->InstanceTemplate()->SetAccessor(
63         StringFromUtf8("value2"),
64         [](Local<String> property, const PropertyCallbackInfo<Value>& args) {
65           args.GetReturnValue().Set(args.Holder()->GetInternalField(1));
66         });
67     for (Local<Context> context :
68          {serialization_context_, deserialization_context_}) {
69       context->Global()
70           ->CreateDataProperty(
71               context, StringFromUtf8("ExampleHostObject"),
72               function_template->GetFunction(context).ToLocalChecked())
73           .ToChecked();
74     }
75     host_object_constructor_template_ = function_template;
76     isolate_ = reinterpret_cast<i::Isolate*>(isolate());
77   }
78 
~ValueSerializerTest()79   ~ValueSerializerTest() override {
80     // In some cases unhandled scheduled exceptions from current test produce
81     // that Context::New(isolate()) from next test's constructor returns NULL.
82     // In order to prevent that, we added destructor which will clear scheduled
83     // exceptions just for the current test from test case.
84     if (isolate_->has_scheduled_exception()) {
85       isolate_->clear_scheduled_exception();
86     }
87   }
88 
serialization_context()89   const Local<Context>& serialization_context() {
90     return serialization_context_;
91   }
deserialization_context()92   const Local<Context>& deserialization_context() {
93     return deserialization_context_;
94   }
95 
96   // Overridden in more specific fixtures.
GetSerializerDelegate()97   virtual ValueSerializer::Delegate* GetSerializerDelegate() { return nullptr; }
BeforeEncode(ValueSerializer *)98   virtual void BeforeEncode(ValueSerializer*) {}
GetDeserializerDelegate()99   virtual ValueDeserializer::Delegate* GetDeserializerDelegate() {
100     return nullptr;
101   }
BeforeDecode(ValueDeserializer *)102   virtual void BeforeDecode(ValueDeserializer*) {}
103 
RoundTripTest(Local<Value> input_value)104   Local<Value> RoundTripTest(Local<Value> input_value) {
105     std::vector<uint8_t> encoded = EncodeTest(input_value);
106     return DecodeTest(encoded);
107   }
108 
109   // Variant for the common case where a script is used to build the original
110   // value.
RoundTripTest(const char * source)111   Local<Value> RoundTripTest(const char* source) {
112     return RoundTripTest(EvaluateScriptForInput(source));
113   }
114 
115   // Variant which uses JSON.parse/stringify to check the result.
RoundTripJSON(const char * source)116   void RoundTripJSON(const char* source) {
117     Local<Value> input_value =
118         JSON::Parse(serialization_context_, StringFromUtf8(source))
119             .ToLocalChecked();
120     Local<Value> result = RoundTripTest(input_value);
121     ASSERT_TRUE(result->IsObject());
122     EXPECT_EQ(source, Utf8Value(JSON::Stringify(deserialization_context_,
123                                                 result.As<Object>())
124                                     .ToLocalChecked()));
125   }
126 
DoEncode(Local<Value> value)127   Maybe<std::vector<uint8_t>> DoEncode(Local<Value> value) {
128     Local<Context> context = serialization_context();
129     ValueSerializer serializer(isolate(), GetSerializerDelegate());
130     BeforeEncode(&serializer);
131     serializer.WriteHeader();
132     if (!serializer.WriteValue(context, value).FromMaybe(false)) {
133       return Nothing<std::vector<uint8_t>>();
134     }
135     std::pair<uint8_t*, size_t> buffer = serializer.Release();
136     std::vector<uint8_t> result(buffer.first, buffer.first + buffer.second);
137     if (auto* delegate = GetSerializerDelegate())
138       delegate->FreeBufferMemory(buffer.first);
139     else
140       free(buffer.first);
141     return Just(std::move(result));
142   }
143 
EncodeTest(Local<Value> input_value)144   std::vector<uint8_t> EncodeTest(Local<Value> input_value) {
145     Context::Scope scope(serialization_context());
146     TryCatch try_catch(isolate());
147     std::vector<uint8_t> buffer;
148     // Ideally we would use GTest's ASSERT_* macros here and below. However,
149     // those only work in functions returning {void}, and they only terminate
150     // the current function, but not the entire current test (so we would need
151     // additional manual checks whether it is okay to proceed). Given that our
152     // test driver starts a new process for each test anyway, it is acceptable
153     // to just use a CHECK (which would kill the process on failure) instead.
154     CHECK(DoEncode(input_value).To(&buffer));
155     CHECK(!try_catch.HasCaught());
156     return buffer;
157   }
158 
EncodeTest(const char * source)159   std::vector<uint8_t> EncodeTest(const char* source) {
160     return EncodeTest(EvaluateScriptForInput(source));
161   }
162 
InvalidEncodeTest(Local<Value> input_value)163   v8::Local<v8::Message> InvalidEncodeTest(Local<Value> input_value) {
164     Context::Scope scope(serialization_context());
165     TryCatch try_catch(isolate());
166     CHECK(DoEncode(input_value).IsNothing());
167     return try_catch.Message();
168   }
169 
InvalidEncodeTest(const char * source)170   v8::Local<v8::Message> InvalidEncodeTest(const char* source) {
171     return InvalidEncodeTest(EvaluateScriptForInput(source));
172   }
173 
DecodeTest(const std::vector<uint8_t> & data)174   Local<Value> DecodeTest(const std::vector<uint8_t>& data) {
175     Local<Context> context = deserialization_context();
176     Context::Scope scope(context);
177     TryCatch try_catch(isolate());
178     ValueDeserializer deserializer(isolate(), &data[0],
179                                    static_cast<int>(data.size()),
180                                    GetDeserializerDelegate());
181     deserializer.SetSupportsLegacyWireFormat(true);
182     BeforeDecode(&deserializer);
183     CHECK(deserializer.ReadHeader(context).FromMaybe(false));
184     Local<Value> result;
185     CHECK(deserializer.ReadValue(context).ToLocal(&result));
186     CHECK(!result.IsEmpty());
187     CHECK(!try_catch.HasCaught());
188     CHECK(context->Global()
189               ->CreateDataProperty(context, StringFromUtf8("result"), result)
190               .FromMaybe(false));
191     CHECK(!try_catch.HasCaught());
192     return result;
193   }
194 
DecodeTestForVersion0(const std::vector<uint8_t> & data)195   Local<Value> DecodeTestForVersion0(const std::vector<uint8_t>& data) {
196     Local<Context> context = deserialization_context();
197     Context::Scope scope(context);
198     TryCatch try_catch(isolate());
199     ValueDeserializer deserializer(isolate(), &data[0],
200                                    static_cast<int>(data.size()),
201                                    GetDeserializerDelegate());
202     deserializer.SetSupportsLegacyWireFormat(true);
203     BeforeDecode(&deserializer);
204     CHECK(deserializer.ReadHeader(context).FromMaybe(false));
205     CHECK_EQ(0u, deserializer.GetWireFormatVersion());
206     Local<Value> result;
207     CHECK(deserializer.ReadValue(context).ToLocal(&result));
208     CHECK(!result.IsEmpty());
209     CHECK(!try_catch.HasCaught());
210     CHECK(context->Global()
211               ->CreateDataProperty(context, StringFromUtf8("result"), result)
212               .FromMaybe(false));
213     CHECK(!try_catch.HasCaught());
214     return result;
215   }
216 
InvalidDecodeTest(const std::vector<uint8_t> & data)217   void InvalidDecodeTest(const std::vector<uint8_t>& data) {
218     Local<Context> context = deserialization_context();
219     Context::Scope scope(context);
220     TryCatch try_catch(isolate());
221     ValueDeserializer deserializer(isolate(), &data[0],
222                                    static_cast<int>(data.size()),
223                                    GetDeserializerDelegate());
224     deserializer.SetSupportsLegacyWireFormat(true);
225     BeforeDecode(&deserializer);
226     Maybe<bool> header_result = deserializer.ReadHeader(context);
227     if (header_result.IsNothing()) {
228       EXPECT_TRUE(try_catch.HasCaught());
229       return;
230     }
231     CHECK(header_result.ToChecked());
232     CHECK(deserializer.ReadValue(context).IsEmpty());
233     EXPECT_TRUE(try_catch.HasCaught());
234   }
235 
EvaluateScriptForInput(const char * utf8_source)236   Local<Value> EvaluateScriptForInput(const char* utf8_source) {
237     Context::Scope scope(serialization_context_);
238     Local<String> source = StringFromUtf8(utf8_source);
239     Local<Script> script =
240         Script::Compile(serialization_context_, source).ToLocalChecked();
241     return script->Run(serialization_context_).ToLocalChecked();
242   }
243 
ExpectScriptTrue(const char * utf8_source)244   void ExpectScriptTrue(const char* utf8_source) {
245     Context::Scope scope(deserialization_context_);
246     Local<String> source = StringFromUtf8(utf8_source);
247     Local<Script> script =
248         Script::Compile(deserialization_context_, source).ToLocalChecked();
249     Local<Value> value = script->Run(deserialization_context_).ToLocalChecked();
250     EXPECT_TRUE(value->BooleanValue(isolate()));
251   }
252 
StringFromUtf8(const char * source)253   Local<String> StringFromUtf8(const char* source) {
254     return String::NewFromUtf8(isolate(), source).ToLocalChecked();
255   }
256 
Utf8Value(Local<Value> value)257   std::string Utf8Value(Local<Value> value) {
258     String::Utf8Value utf8(isolate(), value);
259     return std::string(*utf8, utf8.length());
260   }
261 
NewHostObject(Local<Context> context,int argc,Local<Value> argv[])262   Local<Object> NewHostObject(Local<Context> context, int argc,
263                               Local<Value> argv[]) {
264     return host_object_constructor_template_->GetFunction(context)
265         .ToLocalChecked()
266         ->NewInstance(context, argc, argv)
267         .ToLocalChecked();
268   }
269 
NewDummyUint8Array()270   Local<Object> NewDummyUint8Array() {
271     const uint8_t data[] = {4, 5, 6};
272     Local<ArrayBuffer> ab = ArrayBuffer::New(isolate(), sizeof(data));
273     memcpy(ab->GetBackingStore()->Data(), data, sizeof(data));
274     return Uint8Array::New(ab, 0, sizeof(data));
275   }
276 
277  private:
278   Local<Context> serialization_context_;
279   Local<Context> deserialization_context_;
280   Local<FunctionTemplate> host_object_constructor_template_;
281   i::Isolate* isolate_;
282 };
283 
TEST_F(ValueSerializerTest,DecodeInvalid)284 TEST_F(ValueSerializerTest, DecodeInvalid) {
285   // Version tag but no content.
286   InvalidDecodeTest({0xFF});
287   // Version too large.
288   InvalidDecodeTest({0xFF, 0x7F, 0x5F});
289   // Nonsense tag.
290   InvalidDecodeTest({0xFF, 0x09, 0xDD});
291 }
292 
TEST_F(ValueSerializerTest,RoundTripOddball)293 TEST_F(ValueSerializerTest, RoundTripOddball) {
294   Local<Value> value = RoundTripTest(Undefined(isolate()));
295   EXPECT_TRUE(value->IsUndefined());
296   value = RoundTripTest(True(isolate()));
297   EXPECT_TRUE(value->IsTrue());
298   value = RoundTripTest(False(isolate()));
299   EXPECT_TRUE(value->IsFalse());
300   value = RoundTripTest(Null(isolate()));
301   EXPECT_TRUE(value->IsNull());
302 }
303 
TEST_F(ValueSerializerTest,DecodeOddball)304 TEST_F(ValueSerializerTest, DecodeOddball) {
305   // What this code is expected to generate.
306   Local<Value> value = DecodeTest({0xFF, 0x09, 0x5F});
307   EXPECT_TRUE(value->IsUndefined());
308   value = DecodeTest({0xFF, 0x09, 0x54});
309   EXPECT_TRUE(value->IsTrue());
310   value = DecodeTest({0xFF, 0x09, 0x46});
311   EXPECT_TRUE(value->IsFalse());
312   value = DecodeTest({0xFF, 0x09, 0x30});
313   EXPECT_TRUE(value->IsNull());
314 
315   // What v9 of the Blink code generates.
316   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x5F, 0x00});
317   EXPECT_TRUE(value->IsUndefined());
318   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x54, 0x00});
319   EXPECT_TRUE(value->IsTrue());
320   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x46, 0x00});
321   EXPECT_TRUE(value->IsFalse());
322   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x30, 0x00});
323   EXPECT_TRUE(value->IsNull());
324 
325   // v0 (with no explicit version).
326   value = DecodeTest({0x5F, 0x00});
327   EXPECT_TRUE(value->IsUndefined());
328   value = DecodeTest({0x54, 0x00});
329   EXPECT_TRUE(value->IsTrue());
330   value = DecodeTest({0x46, 0x00});
331   EXPECT_TRUE(value->IsFalse());
332   value = DecodeTest({0x30, 0x00});
333   EXPECT_TRUE(value->IsNull());
334 }
335 
TEST_F(ValueSerializerTest,EncodeArrayStackOverflow)336 TEST_F(ValueSerializerTest, EncodeArrayStackOverflow) {
337   InvalidEncodeTest("var a = []; for (var i = 0; i < 1E5; i++) a = [a]; a");
338 }
339 
TEST_F(ValueSerializerTest,EncodeObjectStackOverflow)340 TEST_F(ValueSerializerTest, EncodeObjectStackOverflow) {
341   InvalidEncodeTest("var a = {}; for (var i = 0; i < 1E5; i++) a = {a}; a");
342 }
343 
TEST_F(ValueSerializerTest,DecodeArrayStackOverflow)344 TEST_F(ValueSerializerTest, DecodeArrayStackOverflow) {
345   static const int nesting_level = 1E5;
346   std::vector<uint8_t> payload;
347   // Header.
348   payload.push_back(0xFF);
349   payload.push_back(0x0D);
350 
351   // Nested arrays, each with one element.
352   for (int i = 0; i < nesting_level; i++) {
353     payload.push_back(0x41);
354     payload.push_back(0x01);
355   }
356 
357   // Innermost array is empty.
358   payload.push_back(0x41);
359   payload.push_back(0x00);
360   payload.push_back(0x24);
361   payload.push_back(0x00);
362   payload.push_back(0x00);
363 
364   // Close nesting.
365   for (int i = 0; i < nesting_level; i++) {
366     payload.push_back(0x24);
367     payload.push_back(0x00);
368     payload.push_back(0x01);
369   }
370 
371   InvalidDecodeTest(payload);
372 }
373 
TEST_F(ValueSerializerTest,DecodeObjectStackOverflow)374 TEST_F(ValueSerializerTest, DecodeObjectStackOverflow) {
375   static const int nesting_level = 1E5;
376   std::vector<uint8_t> payload;
377   // Header.
378   payload.push_back(0xFF);
379   payload.push_back(0x0D);
380 
381   // Nested objects, each with one property 'a'.
382   for (int i = 0; i < nesting_level; i++) {
383     payload.push_back(0x6F);
384     payload.push_back(0x22);
385     payload.push_back(0x01);
386     payload.push_back(0x61);
387   }
388 
389   // Innermost array is empty.
390   payload.push_back(0x6F);
391   payload.push_back(0x7B);
392   payload.push_back(0x00);
393 
394   // Close nesting.
395   for (int i = 0; i < nesting_level; i++) {
396     payload.push_back(0x7B);
397     payload.push_back(0x01);
398   }
399 
400   InvalidDecodeTest(payload);
401 }
402 
TEST_F(ValueSerializerTest,DecodeVerifyObjectCount)403 TEST_F(ValueSerializerTest, DecodeVerifyObjectCount) {
404   static const int nesting_level = 1E5;
405   std::vector<uint8_t> payload;
406   // Header.
407   payload.push_back(0xFF);
408   payload.push_back(0x0D);
409 
410   // Repeat SerializationTag:kVerifyObjectCount. This leads to stack overflow.
411   for (int i = 0; i < nesting_level; i++) {
412     payload.push_back(0x3F);
413     payload.push_back(0x01);
414   }
415 
416   InvalidDecodeTest(payload);
417 }
418 
TEST_F(ValueSerializerTest,RoundTripNumber)419 TEST_F(ValueSerializerTest, RoundTripNumber) {
420   Local<Value> value = RoundTripTest(Integer::New(isolate(), 42));
421   ASSERT_TRUE(value->IsInt32());
422   EXPECT_EQ(42, Int32::Cast(*value)->Value());
423 
424   value = RoundTripTest(Integer::New(isolate(), -31337));
425   ASSERT_TRUE(value->IsInt32());
426   EXPECT_EQ(-31337, Int32::Cast(*value)->Value());
427 
428   value = RoundTripTest(
429       Integer::New(isolate(), std::numeric_limits<int32_t>::min()));
430   ASSERT_TRUE(value->IsInt32());
431   EXPECT_EQ(std::numeric_limits<int32_t>::min(), Int32::Cast(*value)->Value());
432 
433   value = RoundTripTest(Number::New(isolate(), -0.25));
434   ASSERT_TRUE(value->IsNumber());
435   EXPECT_EQ(-0.25, Number::Cast(*value)->Value());
436 
437   value = RoundTripTest(
438       Number::New(isolate(), std::numeric_limits<double>::quiet_NaN()));
439   ASSERT_TRUE(value->IsNumber());
440   EXPECT_TRUE(std::isnan(Number::Cast(*value)->Value()));
441 }
442 
TEST_F(ValueSerializerTest,DecodeNumber)443 TEST_F(ValueSerializerTest, DecodeNumber) {
444   // 42 zig-zag encoded (signed)
445   Local<Value> value = DecodeTest({0xFF, 0x09, 0x49, 0x54});
446   ASSERT_TRUE(value->IsInt32());
447   EXPECT_EQ(42, Int32::Cast(*value)->Value());
448 
449   // 42 varint encoded (unsigned)
450   value = DecodeTest({0xFF, 0x09, 0x55, 0x2A});
451   ASSERT_TRUE(value->IsInt32());
452   EXPECT_EQ(42, Int32::Cast(*value)->Value());
453 
454   // 160 zig-zag encoded (signed)
455   value = DecodeTest({0xFF, 0x09, 0x49, 0xC0, 0x02});
456   ASSERT_TRUE(value->IsInt32());
457   ASSERT_EQ(160, Int32::Cast(*value)->Value());
458 
459   // 160 varint encoded (unsigned)
460   value = DecodeTest({0xFF, 0x09, 0x55, 0xA0, 0x01});
461   ASSERT_TRUE(value->IsInt32());
462   ASSERT_EQ(160, Int32::Cast(*value)->Value());
463 
464 #if defined(V8_TARGET_LITTLE_ENDIAN)
465   // IEEE 754 doubles, little-endian byte order
466   value = DecodeTest(
467       {0xFF, 0x09, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD0, 0xBF});
468   ASSERT_TRUE(value->IsNumber());
469   EXPECT_EQ(-0.25, Number::Cast(*value)->Value());
470 
471   // quiet NaN
472   value = DecodeTest(
473       {0xFF, 0x09, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x7F});
474   ASSERT_TRUE(value->IsNumber());
475   EXPECT_TRUE(std::isnan(Number::Cast(*value)->Value()));
476 
477   // signaling NaN
478   value = DecodeTest(
479       {0xFF, 0x09, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF4, 0x7F});
480   ASSERT_TRUE(value->IsNumber());
481   EXPECT_TRUE(std::isnan(Number::Cast(*value)->Value()));
482 #endif
483   // TODO(jbroman): Equivalent test for big-endian machines.
484 }
485 
TEST_F(ValueSerializerTest,RoundTripBigInt)486 TEST_F(ValueSerializerTest, RoundTripBigInt) {
487   Local<Value> value = RoundTripTest(BigInt::New(isolate(), -42));
488   ASSERT_TRUE(value->IsBigInt());
489   ExpectScriptTrue("result === -42n");
490 
491   value = RoundTripTest(BigInt::New(isolate(), 42));
492   ExpectScriptTrue("result === 42n");
493 
494   value = RoundTripTest(BigInt::New(isolate(), 0));
495   ExpectScriptTrue("result === 0n");
496 
497   value = RoundTripTest("0x1234567890abcdef777888999n");
498   ExpectScriptTrue("result === 0x1234567890abcdef777888999n");
499 
500   value = RoundTripTest("-0x1234567890abcdef777888999123n");
501   ExpectScriptTrue("result === -0x1234567890abcdef777888999123n");
502 
503   Context::Scope scope(serialization_context());
504   value = RoundTripTest(BigIntObject::New(isolate(), 23));
505   ASSERT_TRUE(value->IsBigIntObject());
506   ExpectScriptTrue("result == 23n");
507 }
508 
TEST_F(ValueSerializerTest,DecodeBigInt)509 TEST_F(ValueSerializerTest, DecodeBigInt) {
510   Local<Value> value = DecodeTest({
511       0xFF, 0x0D,              // Version 13
512       0x5A,                    // BigInt
513       0x08,                    // Bitfield: sign = false, bytelength = 4
514       0x2A, 0x00, 0x00, 0x00,  // Digit: 42
515   });
516   ASSERT_TRUE(value->IsBigInt());
517   ExpectScriptTrue("result === 42n");
518 
519   value = DecodeTest({
520       0xFF, 0x0D,  // Version 13
521       0x7A,        // BigIntObject
522       0x11,        // Bitfield: sign = true, bytelength = 8
523       0x2A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00  // Digit: 42
524   });
525   ASSERT_TRUE(value->IsBigIntObject());
526   ExpectScriptTrue("result == -42n");
527 
528   value = DecodeTest({
529       0xFF, 0x0D,  // Version 13
530       0x5A,        // BigInt
531       0x10,        // Bitfield: sign = false, bytelength = 8
532       0xEF, 0xCD, 0xAB, 0x90, 0x78, 0x56, 0x34, 0x12  // Digit(s).
533   });
534   ExpectScriptTrue("result === 0x1234567890abcdefn");
535 
536   value = DecodeTest({0xFF, 0x0D,  // Version 13
537                       0x5A,        // BigInt
538                       0x17,        // Bitfield: sign = true, bytelength = 11
539                       0xEF, 0xCD, 0xAB, 0x90,  // Digits.
540                       0x78, 0x56, 0x34, 0x12, 0x33, 0x44, 0x55});
541   ExpectScriptTrue("result === -0x5544331234567890abcdefn");
542 
543   value = DecodeTest({
544       0xFF, 0x0D,  // Version 13
545       0x5A,        // BigInt
546       0x02,        // Bitfield: sign = false, bytelength = 1
547       0x2A,        // Digit: 42
548   });
549   ExpectScriptTrue("result === 42n");
550 }
551 
552 // String constants (in UTF-8) used for string encoding tests.
553 static const char kHelloString[] = "Hello";
554 static const char kQuebecString[] = "\x51\x75\xC3\xA9\x62\x65\x63";
555 static const char kEmojiString[] = "\xF0\x9F\x91\x8A";
556 
TEST_F(ValueSerializerTest,RoundTripString)557 TEST_F(ValueSerializerTest, RoundTripString) {
558   Local<Value> value = RoundTripTest(String::Empty(isolate()));
559   ASSERT_TRUE(value->IsString());
560   EXPECT_EQ(0, String::Cast(*value)->Length());
561 
562   // Inside ASCII.
563   value = RoundTripTest(StringFromUtf8(kHelloString));
564   ASSERT_TRUE(value->IsString());
565   EXPECT_EQ(5, String::Cast(*value)->Length());
566   EXPECT_EQ(kHelloString, Utf8Value(value));
567 
568   // Inside Latin-1 (i.e. one-byte string), but not ASCII.
569   value = RoundTripTest(StringFromUtf8(kQuebecString));
570   ASSERT_TRUE(value->IsString());
571   EXPECT_EQ(6, String::Cast(*value)->Length());
572   EXPECT_EQ(kQuebecString, Utf8Value(value));
573 
574   // An emoji (decodes to two 16-bit chars).
575   value = RoundTripTest(StringFromUtf8(kEmojiString));
576   ASSERT_TRUE(value->IsString());
577   EXPECT_EQ(2, String::Cast(*value)->Length());
578   EXPECT_EQ(kEmojiString, Utf8Value(value));
579 }
580 
TEST_F(ValueSerializerTest,DecodeString)581 TEST_F(ValueSerializerTest, DecodeString) {
582   // Decoding the strings above from UTF-8.
583   Local<Value> value = DecodeTest({0xFF, 0x09, 0x53, 0x00});
584   ASSERT_TRUE(value->IsString());
585   EXPECT_EQ(0, String::Cast(*value)->Length());
586 
587   value = DecodeTest({0xFF, 0x09, 0x53, 0x05, 'H', 'e', 'l', 'l', 'o'});
588   ASSERT_TRUE(value->IsString());
589   EXPECT_EQ(5, String::Cast(*value)->Length());
590   EXPECT_EQ(kHelloString, Utf8Value(value));
591 
592   value =
593       DecodeTest({0xFF, 0x09, 0x53, 0x07, 'Q', 'u', 0xC3, 0xA9, 'b', 'e', 'c'});
594   ASSERT_TRUE(value->IsString());
595   EXPECT_EQ(6, String::Cast(*value)->Length());
596   EXPECT_EQ(kQuebecString, Utf8Value(value));
597 
598   value = DecodeTest({0xFF, 0x09, 0x53, 0x04, 0xF0, 0x9F, 0x91, 0x8A});
599   ASSERT_TRUE(value->IsString());
600   EXPECT_EQ(2, String::Cast(*value)->Length());
601   EXPECT_EQ(kEmojiString, Utf8Value(value));
602 
603   // And from Latin-1 (for the ones that fit).
604   value = DecodeTest({0xFF, 0x0A, 0x22, 0x00});
605   ASSERT_TRUE(value->IsString());
606   EXPECT_EQ(0, String::Cast(*value)->Length());
607 
608   value = DecodeTest({0xFF, 0x0A, 0x22, 0x05, 'H', 'e', 'l', 'l', 'o'});
609   ASSERT_TRUE(value->IsString());
610   EXPECT_EQ(5, String::Cast(*value)->Length());
611   EXPECT_EQ(kHelloString, Utf8Value(value));
612 
613   value = DecodeTest({0xFF, 0x0A, 0x22, 0x06, 'Q', 'u', 0xE9, 'b', 'e', 'c'});
614   ASSERT_TRUE(value->IsString());
615   EXPECT_EQ(6, String::Cast(*value)->Length());
616   EXPECT_EQ(kQuebecString, Utf8Value(value));
617 
618 // And from two-byte strings (endianness dependent).
619 #if defined(V8_TARGET_LITTLE_ENDIAN)
620   value = DecodeTest({0xFF, 0x09, 0x63, 0x00});
621   ASSERT_TRUE(value->IsString());
622   EXPECT_EQ(0, String::Cast(*value)->Length());
623 
624   value = DecodeTest({0xFF, 0x09, 0x63, 0x0A, 'H', '\0', 'e', '\0', 'l', '\0',
625                       'l', '\0', 'o', '\0'});
626   ASSERT_TRUE(value->IsString());
627   EXPECT_EQ(5, String::Cast(*value)->Length());
628   EXPECT_EQ(kHelloString, Utf8Value(value));
629 
630   value = DecodeTest({0xFF, 0x09, 0x63, 0x0C, 'Q', '\0', 'u', '\0', 0xE9, '\0',
631                       'b', '\0', 'e', '\0', 'c', '\0'});
632   ASSERT_TRUE(value->IsString());
633   EXPECT_EQ(6, String::Cast(*value)->Length());
634   EXPECT_EQ(kQuebecString, Utf8Value(value));
635 
636   value = DecodeTest({0xFF, 0x09, 0x63, 0x04, 0x3D, 0xD8, 0x4A, 0xDC});
637   ASSERT_TRUE(value->IsString());
638   EXPECT_EQ(2, String::Cast(*value)->Length());
639   EXPECT_EQ(kEmojiString, Utf8Value(value));
640 #endif
641   // TODO(jbroman): The same for big-endian systems.
642 }
643 
TEST_F(ValueSerializerTest,DecodeInvalidString)644 TEST_F(ValueSerializerTest, DecodeInvalidString) {
645   // UTF-8 string with too few bytes available.
646   InvalidDecodeTest({0xFF, 0x09, 0x53, 0x10, 'v', '8'});
647   // One-byte string with too few bytes available.
648   InvalidDecodeTest({0xFF, 0x0A, 0x22, 0x10, 'v', '8'});
649 #if defined(V8_TARGET_LITTLE_ENDIAN)
650   // Two-byte string with too few bytes available.
651   InvalidDecodeTest({0xFF, 0x09, 0x63, 0x10, 'v', '\0', '8', '\0'});
652   // Two-byte string with an odd byte length.
653   InvalidDecodeTest({0xFF, 0x09, 0x63, 0x03, 'v', '\0', '8'});
654 #endif
655   // TODO(jbroman): The same for big-endian systems.
656 }
657 
TEST_F(ValueSerializerTest,EncodeTwoByteStringUsesPadding)658 TEST_F(ValueSerializerTest, EncodeTwoByteStringUsesPadding) {
659   // As long as the output has a version that Blink expects to be able to read,
660   // we must respect its alignment requirements. It requires that two-byte
661   // characters be aligned.
662   // We need a string whose length will take two bytes to encode, so that
663   // a padding byte is needed to keep the characters aligned. The string
664   // must also have a two-byte character, so that it gets the two-byte
665   // encoding.
666   std::string string(200, ' ');
667   string += kEmojiString;
668   const std::vector<uint8_t> data = EncodeTest(StringFromUtf8(string.c_str()));
669   // This is a sufficient but not necessary condition. This test assumes
670   // that the wire format version is one byte long, but is flexible to
671   // what that value may be.
672   const uint8_t expected_prefix[] = {0x00, 0x63, 0x94, 0x03};
673   ASSERT_GT(data.size(), sizeof(expected_prefix) + 2);
674   EXPECT_EQ(0xFF, data[0]);
675   EXPECT_GE(data[1], 0x09);
676   EXPECT_LE(data[1], 0x7F);
677   EXPECT_TRUE(std::equal(std::begin(expected_prefix), std::end(expected_prefix),
678                          data.begin() + 2));
679 }
680 
TEST_F(ValueSerializerTest,RoundTripDictionaryObject)681 TEST_F(ValueSerializerTest, RoundTripDictionaryObject) {
682   // Empty object.
683   Local<Value> value = RoundTripTest("({})");
684   ASSERT_TRUE(value->IsObject());
685   ExpectScriptTrue("Object.getPrototypeOf(result) === Object.prototype");
686   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 0");
687 
688   // String key.
689   value = RoundTripTest("({ a: 42 })");
690   ASSERT_TRUE(value->IsObject());
691   ExpectScriptTrue("result.hasOwnProperty('a')");
692   ExpectScriptTrue("result.a === 42");
693   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 1");
694 
695   // Integer key (treated as a string, but may be encoded differently).
696   value = RoundTripTest("({ 42: 'a' })");
697   ASSERT_TRUE(value->IsObject());
698   ExpectScriptTrue("result.hasOwnProperty('42')");
699   ExpectScriptTrue("result[42] === 'a'");
700   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 1");
701 
702   // Key order must be preserved.
703   value = RoundTripTest("({ x: 1, y: 2, a: 3 })");
704   ExpectScriptTrue("Object.getOwnPropertyNames(result).toString() === 'x,y,a'");
705 
706   // A harder case of enumeration order.
707   // Indexes first, in order (but not 2^32 - 1, which is not an index), then the
708   // remaining (string) keys, in the order they were defined.
709   value = RoundTripTest("({ a: 2, 0xFFFFFFFF: 1, 0xFFFFFFFE: 3, 1: 0 })");
710   ExpectScriptTrue(
711       "Object.getOwnPropertyNames(result).toString() === "
712       "'1,4294967294,a,4294967295'");
713   ExpectScriptTrue("result.a === 2");
714   ExpectScriptTrue("result[0xFFFFFFFF] === 1");
715   ExpectScriptTrue("result[0xFFFFFFFE] === 3");
716   ExpectScriptTrue("result[1] === 0");
717 
718   // This detects a fairly subtle case: the object itself must be in the map
719   // before its properties are deserialized, so that references to it can be
720   // resolved.
721   value = RoundTripTest("var y = {}; y.self = y; y;");
722   ASSERT_TRUE(value->IsObject());
723   ExpectScriptTrue("result === result.self");
724 }
725 
TEST_F(ValueSerializerTest,DecodeDictionaryObject)726 TEST_F(ValueSerializerTest, DecodeDictionaryObject) {
727   // Empty object.
728   Local<Value> value =
729       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x7B, 0x00, 0x00});
730   ASSERT_TRUE(value->IsObject());
731   ExpectScriptTrue("Object.getPrototypeOf(result) === Object.prototype");
732   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 0");
733 
734   // String key.
735   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x01,
736                       0x61, 0x3F, 0x01, 0x49, 0x54, 0x7B, 0x01});
737   ASSERT_TRUE(value->IsObject());
738   ExpectScriptTrue("result.hasOwnProperty('a')");
739   ExpectScriptTrue("result.a === 42");
740   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 1");
741 
742   // Integer key (treated as a string, but may be encoded differently).
743   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x49, 0x54,
744                       0x3F, 0x01, 0x53, 0x01, 0x61, 0x7B, 0x01});
745   ASSERT_TRUE(value->IsObject());
746   ExpectScriptTrue("result.hasOwnProperty('42')");
747   ExpectScriptTrue("result[42] === 'a'");
748   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 1");
749 
750   // Key order must be preserved.
751   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x01,
752                       0x78, 0x3F, 0x01, 0x49, 0x02, 0x3F, 0x01, 0x53, 0x01,
753                       0x79, 0x3F, 0x01, 0x49, 0x04, 0x3F, 0x01, 0x53, 0x01,
754                       0x61, 0x3F, 0x01, 0x49, 0x06, 0x7B, 0x03});
755   ExpectScriptTrue("Object.getOwnPropertyNames(result).toString() === 'x,y,a'");
756 
757   // A harder case of enumeration order.
758   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x49, 0x02,
759                       0x3F, 0x01, 0x49, 0x00, 0x3F, 0x01, 0x55, 0xFE, 0xFF,
760                       0xFF, 0xFF, 0x0F, 0x3F, 0x01, 0x49, 0x06, 0x3F, 0x01,
761                       0x53, 0x01, 0x61, 0x3F, 0x01, 0x49, 0x04, 0x3F, 0x01,
762                       0x53, 0x0A, 0x34, 0x32, 0x39, 0x34, 0x39, 0x36, 0x37,
763                       0x32, 0x39, 0x35, 0x3F, 0x01, 0x49, 0x02, 0x7B, 0x04});
764   ExpectScriptTrue(
765       "Object.getOwnPropertyNames(result).toString() === "
766       "'1,4294967294,a,4294967295'");
767   ExpectScriptTrue("result.a === 2");
768   ExpectScriptTrue("result[0xFFFFFFFF] === 1");
769   ExpectScriptTrue("result[0xFFFFFFFE] === 3");
770   ExpectScriptTrue("result[1] === 0");
771 
772   // This detects a fairly subtle case: the object itself must be in the map
773   // before its properties are deserialized, so that references to it can be
774   // resolved.
775   value =
776       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x04, 0x73,
777                   0x65, 0x6C, 0x66, 0x3F, 0x01, 0x5E, 0x00, 0x7B, 0x01, 0x00});
778   ASSERT_TRUE(value->IsObject());
779   ExpectScriptTrue("result === result.self");
780 }
781 
TEST_F(ValueSerializerTest,InvalidDecodeObjectWithInvalidKeyType)782 TEST_F(ValueSerializerTest, InvalidDecodeObjectWithInvalidKeyType) {
783   // Objects which would need conversion to string shouldn't be present as
784   // object keys. The serializer would have obtained them from the own property
785   // keys list, which should only contain names and indices.
786   InvalidDecodeTest(
787       {0xFF, 0x09, 0x6F, 0x61, 0x00, 0x40, 0x00, 0x00, 0x7B, 0x01});
788 }
789 
TEST_F(ValueSerializerTest,RoundTripOnlyOwnEnumerableStringKeys)790 TEST_F(ValueSerializerTest, RoundTripOnlyOwnEnumerableStringKeys) {
791   // Only "own" properties should be serialized, not ones on the prototype.
792   Local<Value> value = RoundTripTest("var x = {}; x.__proto__ = {a: 4}; x;");
793   ExpectScriptTrue("!('a' in result)");
794 
795   // Only enumerable properties should be serialized.
796   value = RoundTripTest(
797       "var x = {};"
798       "Object.defineProperty(x, 'a', {value: 1, enumerable: false});"
799       "x;");
800   ExpectScriptTrue("!('a' in result)");
801 
802   // Symbol keys should not be serialized.
803   value = RoundTripTest("({ [Symbol()]: 4 })");
804   ExpectScriptTrue("Object.getOwnPropertySymbols(result).length === 0");
805 }
806 
TEST_F(ValueSerializerTest,RoundTripTrickyGetters)807 TEST_F(ValueSerializerTest, RoundTripTrickyGetters) {
808   // Keys are enumerated before any setters are called, but if there is no own
809   // property when the value is to be read, then it should not be serialized.
810   Local<Value> value =
811       RoundTripTest("({ get a() { delete this.b; return 1; }, b: 2 })");
812   ExpectScriptTrue("!('b' in result)");
813 
814   // Keys added after the property enumeration should not be serialized.
815   value = RoundTripTest("({ get a() { this.b = 3; }})");
816   ExpectScriptTrue("!('b' in result)");
817 
818   // But if you remove a key and add it back, that's fine. But it will appear in
819   // the original place in enumeration order.
820   value =
821       RoundTripTest("({ get a() { delete this.b; this.b = 4; }, b: 2, c: 3 })");
822   ExpectScriptTrue("Object.getOwnPropertyNames(result).toString() === 'a,b,c'");
823   ExpectScriptTrue("result.b === 4");
824 
825   // Similarly, it only matters if a property was enumerable when the
826   // enumeration happened.
827   value = RoundTripTest(
828       "({ get a() {"
829       "    Object.defineProperty(this, 'b', {value: 2, enumerable: false});"
830       "}, b: 1})");
831   ExpectScriptTrue("result.b === 2");
832 
833   value = RoundTripTest(
834       "var x = {"
835       "  get a() {"
836       "    Object.defineProperty(this, 'b', {value: 2, enumerable: true});"
837       "  }"
838       "};"
839       "Object.defineProperty(x, 'b',"
840       "    {value: 1, enumerable: false, configurable: true});"
841       "x;");
842   ExpectScriptTrue("!('b' in result)");
843 
844   // The property also should not be read if it can only be found on the
845   // prototype chain (but not as an own property) after enumeration.
846   value = RoundTripTest(
847       "var x = { get a() { delete this.b; }, b: 1 };"
848       "x.__proto__ = { b: 0 };"
849       "x;");
850   ExpectScriptTrue("!('b' in result)");
851 
852   // If an exception is thrown by script, encoding must fail and the exception
853   // must be thrown.
854   Local<Message> message =
855       InvalidEncodeTest("({ get a() { throw new Error('sentinel'); } })");
856   ASSERT_FALSE(message.IsEmpty());
857   EXPECT_NE(std::string::npos, Utf8Value(message->Get()).find("sentinel"));
858 }
859 
TEST_F(ValueSerializerTest,RoundTripDictionaryObjectForTransitions)860 TEST_F(ValueSerializerTest, RoundTripDictionaryObjectForTransitions) {
861   // A case which should run on the fast path, and should reach all of the
862   // different cases:
863   // 1. no known transition (first time creating this kind of object)
864   // 2. expected transitions match to end
865   // 3. transition partially matches, but falls back due to new property 'w'
866   // 4. transition to 'z' is now a full transition (needs to be looked up)
867   // 5. same for 'w'
868   // 6. new property after complex transition succeeded
869   // 7. new property after complex transition failed (due to new property)
870   RoundTripJSON(
871       "[{\"x\":1,\"y\":2,\"z\":3}"
872       ",{\"x\":4,\"y\":5,\"z\":6}"
873       ",{\"x\":5,\"y\":6,\"w\":7}"
874       ",{\"x\":6,\"y\":7,\"z\":8}"
875       ",{\"x\":0,\"y\":0,\"w\":0}"
876       ",{\"x\":3,\"y\":1,\"w\":4,\"z\":1}"
877       ",{\"x\":5,\"y\":9,\"k\":2,\"z\":6}]");
878   // A simpler case that uses two-byte strings.
879   RoundTripJSON(
880       "[{\"\xF0\x9F\x91\x8A\":1,\"\xF0\x9F\x91\x8B\":2}"
881       ",{\"\xF0\x9F\x91\x8A\":3,\"\xF0\x9F\x91\x8C\":4}"
882       ",{\"\xF0\x9F\x91\x8A\":5,\"\xF0\x9F\x91\x9B\":6}]");
883 }
884 
TEST_F(ValueSerializerTest,DecodeDictionaryObjectVersion0)885 TEST_F(ValueSerializerTest, DecodeDictionaryObjectVersion0) {
886   // Empty object.
887   Local<Value> value = DecodeTestForVersion0({0x7B, 0x00});
888   ASSERT_TRUE(value->IsObject());
889   ExpectScriptTrue("Object.getPrototypeOf(result) === Object.prototype");
890   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 0");
891 
892   // String key.
893   value =
894       DecodeTestForVersion0({0x53, 0x01, 0x61, 0x49, 0x54, 0x7B, 0x01, 0x00});
895   ASSERT_TRUE(value->IsObject());
896   ExpectScriptTrue("Object.getPrototypeOf(result) === Object.prototype");
897   ExpectScriptTrue("result.hasOwnProperty('a')");
898   ExpectScriptTrue("result.a === 42");
899   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 1");
900 
901   // Integer key (treated as a string, but may be encoded differently).
902   value =
903       DecodeTestForVersion0({0x49, 0x54, 0x53, 0x01, 0x61, 0x7B, 0x01, 0x00});
904   ASSERT_TRUE(value->IsObject());
905   ExpectScriptTrue("result.hasOwnProperty('42')");
906   ExpectScriptTrue("result[42] === 'a'");
907   ExpectScriptTrue("Object.getOwnPropertyNames(result).length === 1");
908 
909   // Key order must be preserved.
910   value = DecodeTestForVersion0({0x53, 0x01, 0x78, 0x49, 0x02, 0x53, 0x01, 0x79,
911                                  0x49, 0x04, 0x53, 0x01, 0x61, 0x49, 0x06, 0x7B,
912                                  0x03, 0x00});
913   ExpectScriptTrue("Object.getOwnPropertyNames(result).toString() === 'x,y,a'");
914 
915   // A property and an element.
916   value = DecodeTestForVersion0(
917       {0x49, 0x54, 0x53, 0x01, 0x61, 0x53, 0x01, 0x61, 0x49, 0x54, 0x7B, 0x02});
918   ExpectScriptTrue("Object.getOwnPropertyNames(result).toString() === '42,a'");
919   ExpectScriptTrue("result[42] === 'a'");
920   ExpectScriptTrue("result.a === 42");
921 }
922 
TEST_F(ValueSerializerTest,RoundTripArray)923 TEST_F(ValueSerializerTest, RoundTripArray) {
924   // A simple array of integers.
925   Local<Value> value = RoundTripTest("[1, 2, 3, 4, 5]");
926   ASSERT_TRUE(value->IsArray());
927   EXPECT_EQ(5u, Array::Cast(*value)->Length());
928   ExpectScriptTrue("Object.getPrototypeOf(result) === Array.prototype");
929   ExpectScriptTrue("result.toString() === '1,2,3,4,5'");
930 
931   // A long (sparse) array.
932   value = RoundTripTest("var x = new Array(1000); x[500] = 42; x;");
933   ASSERT_TRUE(value->IsArray());
934   EXPECT_EQ(1000u, Array::Cast(*value)->Length());
935   ExpectScriptTrue("result[500] === 42");
936 
937   // Duplicate reference.
938   value = RoundTripTest("var y = {}; [y, y];");
939   ASSERT_TRUE(value->IsArray());
940   ASSERT_EQ(2u, Array::Cast(*value)->Length());
941   ExpectScriptTrue("result[0] === result[1]");
942 
943   // Duplicate reference in a sparse array.
944   value = RoundTripTest("var x = new Array(1000); x[1] = x[500] = {}; x;");
945   ASSERT_TRUE(value->IsArray());
946   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
947   ExpectScriptTrue("typeof result[1] === 'object'");
948   ExpectScriptTrue("result[1] === result[500]");
949 
950   // Self reference.
951   value = RoundTripTest("var y = []; y[0] = y; y;");
952   ASSERT_TRUE(value->IsArray());
953   ASSERT_EQ(1u, Array::Cast(*value)->Length());
954   ExpectScriptTrue("result[0] === result");
955 
956   // Self reference in a sparse array.
957   value = RoundTripTest("var y = new Array(1000); y[519] = y; y;");
958   ASSERT_TRUE(value->IsArray());
959   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
960   ExpectScriptTrue("result[519] === result");
961 
962   // Array with additional properties.
963   value = RoundTripTest("var y = [1, 2]; y.foo = 'bar'; y;");
964   ASSERT_TRUE(value->IsArray());
965   ASSERT_EQ(2u, Array::Cast(*value)->Length());
966   ExpectScriptTrue("result.toString() === '1,2'");
967   ExpectScriptTrue("result.foo === 'bar'");
968 
969   // Sparse array with additional properties.
970   value = RoundTripTest("var y = new Array(1000); y.foo = 'bar'; y;");
971   ASSERT_TRUE(value->IsArray());
972   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
973   ExpectScriptTrue("result.toString() === ','.repeat(999)");
974   ExpectScriptTrue("result.foo === 'bar'");
975 
976   // The distinction between holes and undefined elements must be maintained.
977   value = RoundTripTest("[,undefined]");
978   ASSERT_TRUE(value->IsArray());
979   ASSERT_EQ(2u, Array::Cast(*value)->Length());
980   ExpectScriptTrue("typeof result[0] === 'undefined'");
981   ExpectScriptTrue("typeof result[1] === 'undefined'");
982   ExpectScriptTrue("!result.hasOwnProperty(0)");
983   ExpectScriptTrue("result.hasOwnProperty(1)");
984 }
985 
TEST_F(ValueSerializerTest,DecodeArray)986 TEST_F(ValueSerializerTest, DecodeArray) {
987   // A simple array of integers.
988   Local<Value> value =
989       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x41, 0x05, 0x3F, 0x01, 0x49, 0x02,
990                   0x3F, 0x01, 0x49, 0x04, 0x3F, 0x01, 0x49, 0x06, 0x3F, 0x01,
991                   0x49, 0x08, 0x3F, 0x01, 0x49, 0x0A, 0x24, 0x00, 0x05, 0x00});
992   ASSERT_TRUE(value->IsArray());
993   EXPECT_EQ(5u, Array::Cast(*value)->Length());
994   ExpectScriptTrue("Object.getPrototypeOf(result) === Array.prototype");
995   ExpectScriptTrue("result.toString() === '1,2,3,4,5'");
996 
997   // A long (sparse) array.
998   value =
999       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x61, 0xE8, 0x07, 0x3F, 0x01, 0x49,
1000                   0xE8, 0x07, 0x3F, 0x01, 0x49, 0x54, 0x40, 0x01, 0xE8, 0x07});
1001   ASSERT_TRUE(value->IsArray());
1002   EXPECT_EQ(1000u, Array::Cast(*value)->Length());
1003   ExpectScriptTrue("result[500] === 42");
1004 
1005   // Duplicate reference.
1006   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x41, 0x02, 0x3F, 0x01, 0x6F,
1007                       0x7B, 0x00, 0x3F, 0x02, 0x5E, 0x01, 0x24, 0x00, 0x02});
1008   ASSERT_TRUE(value->IsArray());
1009   ASSERT_EQ(2u, Array::Cast(*value)->Length());
1010   ExpectScriptTrue("result[0] === result[1]");
1011 
1012   // Duplicate reference in a sparse array.
1013   value =
1014       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x61, 0xE8, 0x07, 0x3F, 0x01, 0x49,
1015                   0x02, 0x3F, 0x01, 0x6F, 0x7B, 0x00, 0x3F, 0x02, 0x49, 0xE8,
1016                   0x07, 0x3F, 0x02, 0x5E, 0x01, 0x40, 0x02, 0xE8, 0x07, 0x00});
1017   ASSERT_TRUE(value->IsArray());
1018   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1019   ExpectScriptTrue("typeof result[1] === 'object'");
1020   ExpectScriptTrue("result[1] === result[500]");
1021 
1022   // Self reference.
1023   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x41, 0x01, 0x3F, 0x01, 0x5E,
1024                       0x00, 0x24, 0x00, 0x01, 0x00});
1025   ASSERT_TRUE(value->IsArray());
1026   ASSERT_EQ(1u, Array::Cast(*value)->Length());
1027   ExpectScriptTrue("result[0] === result");
1028 
1029   // Self reference in a sparse array.
1030   value =
1031       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x61, 0xE8, 0x07, 0x3F, 0x01, 0x49,
1032                   0x8E, 0x08, 0x3F, 0x01, 0x5E, 0x00, 0x40, 0x01, 0xE8, 0x07});
1033   ASSERT_TRUE(value->IsArray());
1034   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1035   ExpectScriptTrue("result[519] === result");
1036 
1037   // Array with additional properties.
1038   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x41, 0x02, 0x3F, 0x01,
1039                       0x49, 0x02, 0x3F, 0x01, 0x49, 0x04, 0x3F, 0x01,
1040                       0x53, 0x03, 0x66, 0x6F, 0x6F, 0x3F, 0x01, 0x53,
1041                       0x03, 0x62, 0x61, 0x72, 0x24, 0x01, 0x02, 0x00});
1042   ASSERT_TRUE(value->IsArray());
1043   ASSERT_EQ(2u, Array::Cast(*value)->Length());
1044   ExpectScriptTrue("result.toString() === '1,2'");
1045   ExpectScriptTrue("result.foo === 'bar'");
1046 
1047   // Sparse array with additional properties.
1048   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x61, 0xE8, 0x07, 0x3F, 0x01,
1049                       0x53, 0x03, 0x66, 0x6F, 0x6F, 0x3F, 0x01, 0x53, 0x03,
1050                       0x62, 0x61, 0x72, 0x40, 0x01, 0xE8, 0x07, 0x00});
1051   ASSERT_TRUE(value->IsArray());
1052   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1053   ExpectScriptTrue("result.toString() === ','.repeat(999)");
1054   ExpectScriptTrue("result.foo === 'bar'");
1055 
1056   // The distinction between holes and undefined elements must be maintained.
1057   // Note that since the previous output from Chrome fails this test, an
1058   // encoding using the sparse format was constructed instead.
1059   value =
1060       DecodeTest({0xFF, 0x09, 0x61, 0x02, 0x49, 0x02, 0x5F, 0x40, 0x01, 0x02});
1061   ASSERT_TRUE(value->IsArray());
1062   ASSERT_EQ(2u, Array::Cast(*value)->Length());
1063   ExpectScriptTrue("typeof result[0] === 'undefined'");
1064   ExpectScriptTrue("typeof result[1] === 'undefined'");
1065   ExpectScriptTrue("!result.hasOwnProperty(0)");
1066   ExpectScriptTrue("result.hasOwnProperty(1)");
1067 }
1068 
TEST_F(ValueSerializerTest,DecodeInvalidOverLargeArray)1069 TEST_F(ValueSerializerTest, DecodeInvalidOverLargeArray) {
1070   // So large it couldn't exist in the V8 heap, and its size couldn't fit in a
1071   // SMI on 32-bit systems (2^30).
1072   InvalidDecodeTest({0xFF, 0x09, 0x41, 0x80, 0x80, 0x80, 0x80, 0x04});
1073   // Not so large, but there isn't enough data left in the buffer.
1074   InvalidDecodeTest({0xFF, 0x09, 0x41, 0x01});
1075 }
1076 
TEST_F(ValueSerializerTest,RoundTripArrayWithNonEnumerableElement)1077 TEST_F(ValueSerializerTest, RoundTripArrayWithNonEnumerableElement) {
1078   // Even though this array looks like [1,5,3], the 5 should be missing from the
1079   // perspective of structured clone, which only clones properties that were
1080   // enumerable.
1081   Local<Value> value = RoundTripTest(
1082       "var x = [1,2,3];"
1083       "Object.defineProperty(x, '1', {enumerable:false, value:5});"
1084       "x;");
1085   ASSERT_TRUE(value->IsArray());
1086   ASSERT_EQ(3u, Array::Cast(*value)->Length());
1087   ExpectScriptTrue("!result.hasOwnProperty('1')");
1088 }
1089 
TEST_F(ValueSerializerTest,RoundTripArrayWithTrickyGetters)1090 TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
1091   // If an element is deleted before it is serialized, then it's deleted.
1092   Local<Value> value =
1093       RoundTripTest("var x = [{ get a() { delete x[1]; }}, 42]; x;");
1094   ASSERT_TRUE(value->IsArray());
1095   ASSERT_EQ(2u, Array::Cast(*value)->Length());
1096   ExpectScriptTrue("typeof result[1] === 'undefined'");
1097   ExpectScriptTrue("!result.hasOwnProperty(1)");
1098 
1099   // Same for sparse arrays.
1100   value = RoundTripTest(
1101       "var x = [{ get a() { delete x[1]; }}, 42];"
1102       "x.length = 1000;"
1103       "x;");
1104   ASSERT_TRUE(value->IsArray());
1105   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1106   ExpectScriptTrue("typeof result[1] === 'undefined'");
1107   ExpectScriptTrue("!result.hasOwnProperty(1)");
1108 
1109   // If the length is changed, then the resulting array still has the original
1110   // length, but elements that were not yet serialized are gone.
1111   value = RoundTripTest("var x = [1, { get a() { x.length = 0; }}, 3, 4]; x;");
1112   ASSERT_TRUE(value->IsArray());
1113   ASSERT_EQ(4u, Array::Cast(*value)->Length());
1114   ExpectScriptTrue("result[0] === 1");
1115   ExpectScriptTrue("!result.hasOwnProperty(2)");
1116 
1117   // The same is true if the length is shortened, but there are still items
1118   // remaining.
1119   value = RoundTripTest("var x = [1, { get a() { x.length = 3; }}, 3, 4]; x;");
1120   ASSERT_TRUE(value->IsArray());
1121   ASSERT_EQ(4u, Array::Cast(*value)->Length());
1122   ExpectScriptTrue("result[2] === 3");
1123   ExpectScriptTrue("!result.hasOwnProperty(3)");
1124 
1125   // Same for sparse arrays.
1126   value = RoundTripTest(
1127       "var x = [1, { get a() { x.length = 0; }}, 3, 4];"
1128       "x.length = 1000;"
1129       "x;");
1130   ASSERT_TRUE(value->IsArray());
1131   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1132   ExpectScriptTrue("result[0] === 1");
1133   ExpectScriptTrue("!result.hasOwnProperty(2)");
1134 
1135   value = RoundTripTest(
1136       "var x = [1, { get a() { x.length = 3; }}, 3, 4];"
1137       "x.length = 1000;"
1138       "x;");
1139   ASSERT_TRUE(value->IsArray());
1140   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1141   ExpectScriptTrue("result[2] === 3");
1142   ExpectScriptTrue("!result.hasOwnProperty(3)");
1143 
1144   // If a getter makes a property non-enumerable, it should still be enumerated
1145   // as enumeration happens once before getters are invoked.
1146   value = RoundTripTest(
1147       "var x = [{ get a() {"
1148       "  Object.defineProperty(x, '1', { value: 3, enumerable: false });"
1149       "}}, 2];"
1150       "x;");
1151   ASSERT_TRUE(value->IsArray());
1152   ASSERT_EQ(2u, Array::Cast(*value)->Length());
1153   ExpectScriptTrue("result[1] === 3");
1154 
1155   // Same for sparse arrays.
1156   value = RoundTripTest(
1157       "var x = [{ get a() {"
1158       "  Object.defineProperty(x, '1', { value: 3, enumerable: false });"
1159       "}}, 2];"
1160       "x.length = 1000;"
1161       "x;");
1162   ASSERT_TRUE(value->IsArray());
1163   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1164   ExpectScriptTrue("result[1] === 3");
1165 
1166   // Getters on the array itself must also run.
1167   value = RoundTripTest(
1168       "var x = [1, 2, 3];"
1169       "Object.defineProperty(x, '1', { enumerable: true, get: () => 4 });"
1170       "x;");
1171   ASSERT_TRUE(value->IsArray());
1172   ASSERT_EQ(3u, Array::Cast(*value)->Length());
1173   ExpectScriptTrue("result[1] === 4");
1174 
1175   // Same for sparse arrays.
1176   value = RoundTripTest(
1177       "var x = [1, 2, 3];"
1178       "Object.defineProperty(x, '1', { enumerable: true, get: () => 4 });"
1179       "x.length = 1000;"
1180       "x;");
1181   ASSERT_TRUE(value->IsArray());
1182   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1183   ExpectScriptTrue("result[1] === 4");
1184 
1185   // Even with a getter that deletes things, we don't read from the prototype.
1186   value = RoundTripTest(
1187       "var x = [{ get a() { delete x[1]; } }, 2];"
1188       "x.__proto__ = Object.create(Array.prototype, { 1: { value: 6 } });"
1189       "x;");
1190   ASSERT_TRUE(value->IsArray());
1191   ASSERT_EQ(2u, Array::Cast(*value)->Length());
1192   ExpectScriptTrue("!(1 in result)");
1193 
1194   // Same for sparse arrays.
1195   value = RoundTripTest(
1196       "var x = [{ get a() { delete x[1]; } }, 2];"
1197       "x.__proto__ = Object.create(Array.prototype, { 1: { value: 6 } });"
1198       "x.length = 1000;"
1199       "x;");
1200   ASSERT_TRUE(value->IsArray());
1201   ASSERT_EQ(1000u, Array::Cast(*value)->Length());
1202   ExpectScriptTrue("!(1 in result)");
1203 }
1204 
TEST_F(ValueSerializerTest,DecodeSparseArrayVersion0)1205 TEST_F(ValueSerializerTest, DecodeSparseArrayVersion0) {
1206   // Empty (sparse) array.
1207   Local<Value> value = DecodeTestForVersion0({0x40, 0x00, 0x00, 0x00});
1208   ASSERT_TRUE(value->IsArray());
1209   ASSERT_EQ(0u, Array::Cast(*value)->Length());
1210 
1211   // Sparse array with a mixture of elements and properties.
1212   value = DecodeTestForVersion0({0x55, 0x00, 0x53, 0x01, 'a',  0x55, 0x02, 0x55,
1213                                  0x05, 0x53, 0x03, 'f',  'o',  'o',  0x53, 0x03,
1214                                  'b',  'a',  'r',  0x53, 0x03, 'b',  'a',  'z',
1215                                  0x49, 0x0B, 0x40, 0x04, 0x03, 0x00});
1216   ASSERT_TRUE(value->IsArray());
1217   EXPECT_EQ(3u, Array::Cast(*value)->Length());
1218   ExpectScriptTrue("result.toString() === 'a,,5'");
1219   ExpectScriptTrue("!(1 in result)");
1220   ExpectScriptTrue("result.foo === 'bar'");
1221   ExpectScriptTrue("result.baz === -6");
1222 
1223   // Sparse array in a sparse array (sanity check of nesting).
1224   value = DecodeTestForVersion0(
1225       {0x55, 0x01, 0x55, 0x01, 0x54, 0x40, 0x01, 0x02, 0x40, 0x01, 0x02, 0x00});
1226   ASSERT_TRUE(value->IsArray());
1227   EXPECT_EQ(2u, Array::Cast(*value)->Length());
1228   ExpectScriptTrue("!(0 in result)");
1229   ExpectScriptTrue("result[1] instanceof Array");
1230   ExpectScriptTrue("!(0 in result[1])");
1231   ExpectScriptTrue("result[1][1] === true");
1232 }
1233 
TEST_F(ValueSerializerTest,RoundTripDenseArrayContainingUndefined)1234 TEST_F(ValueSerializerTest, RoundTripDenseArrayContainingUndefined) {
1235   // In previous serialization versions, this would be interpreted as an absent
1236   // property.
1237   Local<Value> value = RoundTripTest("[undefined]");
1238   ASSERT_TRUE(value->IsArray());
1239   EXPECT_EQ(1u, Array::Cast(*value)->Length());
1240   ExpectScriptTrue("result.hasOwnProperty(0)");
1241   ExpectScriptTrue("result[0] === undefined");
1242 }
1243 
TEST_F(ValueSerializerTest,DecodeDenseArrayContainingUndefined)1244 TEST_F(ValueSerializerTest, DecodeDenseArrayContainingUndefined) {
1245   // In previous versions, "undefined" in a dense array signified absence of the
1246   // element (for compatibility). In new versions, it has a separate encoding.
1247   Local<Value> value =
1248       DecodeTest({0xFF, 0x09, 0x41, 0x01, 0x5F, 0x24, 0x00, 0x01});
1249   ExpectScriptTrue("!(0 in result)");
1250 
1251   value = DecodeTest({0xFF, 0x0B, 0x41, 0x01, 0x5F, 0x24, 0x00, 0x01});
1252   ExpectScriptTrue("0 in result");
1253   ExpectScriptTrue("result[0] === undefined");
1254 
1255   value = DecodeTest({0xFF, 0x0B, 0x41, 0x01, 0x2D, 0x24, 0x00, 0x01});
1256   ExpectScriptTrue("!(0 in result)");
1257 }
1258 
TEST_F(ValueSerializerTest,RoundTripDate)1259 TEST_F(ValueSerializerTest, RoundTripDate) {
1260   Local<Value> value = RoundTripTest("new Date(1e6)");
1261   ASSERT_TRUE(value->IsDate());
1262   EXPECT_EQ(1e6, Date::Cast(*value)->ValueOf());
1263   ExpectScriptTrue("Object.getPrototypeOf(result) === Date.prototype");
1264 
1265   value = RoundTripTest("new Date(Date.UTC(1867, 6, 1))");
1266   ASSERT_TRUE(value->IsDate());
1267   ExpectScriptTrue("result.toISOString() === '1867-07-01T00:00:00.000Z'");
1268 
1269   value = RoundTripTest("new Date(NaN)");
1270   ASSERT_TRUE(value->IsDate());
1271   EXPECT_TRUE(std::isnan(Date::Cast(*value)->ValueOf()));
1272 
1273   value = RoundTripTest("({ a: new Date(), get b() { return this.a; } })");
1274   ExpectScriptTrue("result.a instanceof Date");
1275   ExpectScriptTrue("result.a === result.b");
1276 }
1277 
TEST_F(ValueSerializerTest,DecodeDate)1278 TEST_F(ValueSerializerTest, DecodeDate) {
1279   Local<Value> value;
1280 #if defined(V8_TARGET_LITTLE_ENDIAN)
1281   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00,
1282                       0x80, 0x84, 0x2E, 0x41, 0x00});
1283   ASSERT_TRUE(value->IsDate());
1284   EXPECT_EQ(1e6, Date::Cast(*value)->ValueOf());
1285   ExpectScriptTrue("Object.getPrototypeOf(result) === Date.prototype");
1286 
1287   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x44, 0x00, 0x00, 0x20, 0x45,
1288                       0x27, 0x89, 0x87, 0xC2, 0x00});
1289   ASSERT_TRUE(value->IsDate());
1290   ExpectScriptTrue("result.toISOString() === '1867-07-01T00:00:00.000Z'");
1291 
1292   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00,
1293                       0x00, 0x00, 0xF8, 0x7F, 0x00});
1294   ASSERT_TRUE(value->IsDate());
1295   EXPECT_TRUE(std::isnan(Date::Cast(*value)->ValueOf()));
1296 #else
1297   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x44, 0x41, 0x2E, 0x84, 0x80,
1298                       0x00, 0x00, 0x00, 0x00, 0x00});
1299   ASSERT_TRUE(value->IsDate());
1300   EXPECT_EQ(1e6, Date::Cast(*value)->ValueOf());
1301   ExpectScriptTrue("Object.getPrototypeOf(result) === Date.prototype");
1302 
1303   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x44, 0xC2, 0x87, 0x89, 0x27,
1304                       0x45, 0x20, 0x00, 0x00, 0x00});
1305   ASSERT_TRUE(value->IsDate());
1306   ExpectScriptTrue("result.toISOString() === '1867-07-01T00:00:00.000Z'");
1307 
1308   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x44, 0x7F, 0xF8, 0x00, 0x00,
1309                       0x00, 0x00, 0x00, 0x00, 0x00});
1310   ASSERT_TRUE(value->IsDate());
1311   EXPECT_TRUE(std::isnan(Date::Cast(*value)->ValueOf()));
1312 #endif
1313   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53,
1314                       0x01, 0x61, 0x3F, 0x01, 0x44, 0x00, 0x20, 0x39,
1315                       0x50, 0x37, 0x6A, 0x75, 0x42, 0x3F, 0x02, 0x53,
1316                       0x01, 0x62, 0x3F, 0x02, 0x5E, 0x01, 0x7B, 0x02});
1317   ExpectScriptTrue("result.a instanceof Date");
1318   ExpectScriptTrue("result.a === result.b");
1319 }
1320 
TEST_F(ValueSerializerTest,RoundTripValueObjects)1321 TEST_F(ValueSerializerTest, RoundTripValueObjects) {
1322   Local<Value> value = RoundTripTest("new Boolean(true)");
1323   ExpectScriptTrue("Object.getPrototypeOf(result) === Boolean.prototype");
1324   ExpectScriptTrue("result.valueOf() === true");
1325 
1326   value = RoundTripTest("new Boolean(false)");
1327   ExpectScriptTrue("Object.getPrototypeOf(result) === Boolean.prototype");
1328   ExpectScriptTrue("result.valueOf() === false");
1329 
1330   value =
1331       RoundTripTest("({ a: new Boolean(true), get b() { return this.a; }})");
1332   ExpectScriptTrue("result.a instanceof Boolean");
1333   ExpectScriptTrue("result.a === result.b");
1334 
1335   value = RoundTripTest("new Number(-42)");
1336   ExpectScriptTrue("Object.getPrototypeOf(result) === Number.prototype");
1337   ExpectScriptTrue("result.valueOf() === -42");
1338 
1339   value = RoundTripTest("new Number(NaN)");
1340   ExpectScriptTrue("Object.getPrototypeOf(result) === Number.prototype");
1341   ExpectScriptTrue("Number.isNaN(result.valueOf())");
1342 
1343   value = RoundTripTest("({ a: new Number(6), get b() { return this.a; }})");
1344   ExpectScriptTrue("result.a instanceof Number");
1345   ExpectScriptTrue("result.a === result.b");
1346 
1347   value = RoundTripTest("new String('Qu\\xe9bec')");
1348   ExpectScriptTrue("Object.getPrototypeOf(result) === String.prototype");
1349   ExpectScriptTrue("result.valueOf() === 'Qu\\xe9bec'");
1350   ExpectScriptTrue("result.length === 6");
1351 
1352   value = RoundTripTest("new String('\\ud83d\\udc4a')");
1353   ExpectScriptTrue("Object.getPrototypeOf(result) === String.prototype");
1354   ExpectScriptTrue("result.valueOf() === '\\ud83d\\udc4a'");
1355   ExpectScriptTrue("result.length === 2");
1356 
1357   value = RoundTripTest("({ a: new String(), get b() { return this.a; }})");
1358   ExpectScriptTrue("result.a instanceof String");
1359   ExpectScriptTrue("result.a === result.b");
1360 }
1361 
TEST_F(ValueSerializerTest,RejectsOtherValueObjects)1362 TEST_F(ValueSerializerTest, RejectsOtherValueObjects) {
1363   // This is a roundabout way of getting an instance of Symbol.
1364   InvalidEncodeTest("Object.valueOf.apply(Symbol())");
1365 }
1366 
TEST_F(ValueSerializerTest,DecodeValueObjects)1367 TEST_F(ValueSerializerTest, DecodeValueObjects) {
1368   Local<Value> value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x79, 0x00});
1369   ExpectScriptTrue("Object.getPrototypeOf(result) === Boolean.prototype");
1370   ExpectScriptTrue("result.valueOf() === true");
1371 
1372   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x78, 0x00});
1373   ExpectScriptTrue("Object.getPrototypeOf(result) === Boolean.prototype");
1374   ExpectScriptTrue("result.valueOf() === false");
1375 
1376   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53,
1377                       0x01, 0x61, 0x3F, 0x01, 0x79, 0x3F, 0x02, 0x53,
1378                       0x01, 0x62, 0x3F, 0x02, 0x5E, 0x01, 0x7B, 0x02});
1379   ExpectScriptTrue("result.a instanceof Boolean");
1380   ExpectScriptTrue("result.a === result.b");
1381 
1382 #if defined(V8_TARGET_LITTLE_ENDIAN)
1383   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00,
1384                       0x00, 0x00, 0x45, 0xC0, 0x00});
1385   ExpectScriptTrue("Object.getPrototypeOf(result) === Number.prototype");
1386   ExpectScriptTrue("result.valueOf() === -42");
1387 
1388   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6E, 0x00, 0x00, 0x00, 0x00,
1389                       0x00, 0x00, 0xF8, 0x7F, 0x00});
1390   ExpectScriptTrue("Object.getPrototypeOf(result) === Number.prototype");
1391   ExpectScriptTrue("Number.isNaN(result.valueOf())");
1392 #else
1393   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6E, 0xC0, 0x45, 0x00, 0x00,
1394                       0x00, 0x00, 0x00, 0x00, 0x00});
1395   ExpectScriptTrue("Object.getPrototypeOf(result) === Number.prototype");
1396   ExpectScriptTrue("result.valueOf() === -42");
1397 
1398   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6E, 0x7F, 0xF8, 0x00, 0x00,
1399                       0x00, 0x00, 0x00, 0x00, 0x00});
1400   ExpectScriptTrue("Object.getPrototypeOf(result) === Number.prototype");
1401   ExpectScriptTrue("Number.isNaN(result.valueOf())");
1402 #endif
1403   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53,
1404                       0x01, 0x61, 0x3F, 0x01, 0x6E, 0x00, 0x00, 0x00,
1405                       0x00, 0x00, 0x00, 0x18, 0x40, 0x3F, 0x02, 0x53,
1406                       0x01, 0x62, 0x3F, 0x02, 0x5E, 0x01, 0x7B, 0x02});
1407   ExpectScriptTrue("result.a instanceof Number");
1408   ExpectScriptTrue("result.a === result.b");
1409 
1410   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x73, 0x07, 0x51, 0x75, 0xC3,
1411                       0xA9, 0x62, 0x65, 0x63, 0x00});
1412   ExpectScriptTrue("Object.getPrototypeOf(result) === String.prototype");
1413   ExpectScriptTrue("result.valueOf() === 'Qu\\xe9bec'");
1414   ExpectScriptTrue("result.length === 6");
1415 
1416   value =
1417       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x73, 0x04, 0xF0, 0x9F, 0x91, 0x8A});
1418   ExpectScriptTrue("Object.getPrototypeOf(result) === String.prototype");
1419   ExpectScriptTrue("result.valueOf() === '\\ud83d\\udc4a'");
1420   ExpectScriptTrue("result.length === 2");
1421 
1422   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x01,
1423                       0x61, 0x3F, 0x01, 0x73, 0x00, 0x3F, 0x02, 0x53, 0x01,
1424                       0x62, 0x3F, 0x02, 0x5E, 0x01, 0x7B, 0x02, 0x00});
1425   ExpectScriptTrue("result.a instanceof String");
1426   ExpectScriptTrue("result.a === result.b");
1427 
1428   // String object containing a Latin-1 string.
1429   value =
1430       DecodeTest({0xFF, 0x0C, 0x73, 0x22, 0x06, 'Q', 'u', 0xE9, 'b', 'e', 'c'});
1431   ExpectScriptTrue("Object.getPrototypeOf(result) === String.prototype");
1432   ExpectScriptTrue("result.valueOf() === 'Qu\\xe9bec'");
1433   ExpectScriptTrue("result.length === 6");
1434 }
1435 
TEST_F(ValueSerializerTest,RoundTripRegExp)1436 TEST_F(ValueSerializerTest, RoundTripRegExp) {
1437   Local<Value> value = RoundTripTest("/foo/g");
1438   ASSERT_TRUE(value->IsRegExp());
1439   ExpectScriptTrue("Object.getPrototypeOf(result) === RegExp.prototype");
1440   ExpectScriptTrue("result.toString() === '/foo/g'");
1441 
1442   value = RoundTripTest("new RegExp('Qu\\xe9bec', 'i')");
1443   ASSERT_TRUE(value->IsRegExp());
1444   ExpectScriptTrue("result.toString() === '/Qu\\xe9bec/i'");
1445 
1446   value = RoundTripTest("new RegExp('\\ud83d\\udc4a', 'ug')");
1447   ASSERT_TRUE(value->IsRegExp());
1448   ExpectScriptTrue("result.toString() === '/\\ud83d\\udc4a/gu'");
1449 
1450   value = RoundTripTest("({ a: /foo/gi, get b() { return this.a; }})");
1451   ExpectScriptTrue("result.a instanceof RegExp");
1452   ExpectScriptTrue("result.a === result.b");
1453 }
1454 
TEST_F(ValueSerializerTest,DecodeRegExp)1455 TEST_F(ValueSerializerTest, DecodeRegExp) {
1456   Local<Value> value =
1457       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x52, 0x03, 0x66, 0x6F, 0x6F, 0x01});
1458   ASSERT_TRUE(value->IsRegExp());
1459   ExpectScriptTrue("Object.getPrototypeOf(result) === RegExp.prototype");
1460   ExpectScriptTrue("result.toString() === '/foo/g'");
1461 
1462   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x52, 0x07, 0x51, 0x75, 0xC3,
1463                       0xA9, 0x62, 0x65, 0x63, 0x02});
1464   ASSERT_TRUE(value->IsRegExp());
1465   ExpectScriptTrue("result.toString() === '/Qu\\xe9bec/i'");
1466 
1467   value = DecodeTest(
1468       {0xFF, 0x09, 0x3F, 0x00, 0x52, 0x04, 0xF0, 0x9F, 0x91, 0x8A, 0x11, 0x00});
1469   ASSERT_TRUE(value->IsRegExp());
1470   ExpectScriptTrue("result.toString() === '/\\ud83d\\udc4a/gu'");
1471 
1472   value =
1473       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x01, 0x61,
1474                   0x3F, 0x01, 0x52, 0x03, 0x66, 0x6F, 0x6F, 0x03, 0x3F, 0x02,
1475                   0x53, 0x01, 0x62, 0x3F, 0x02, 0x5E, 0x01, 0x7B, 0x02, 0x00});
1476   ExpectScriptTrue("result.a instanceof RegExp");
1477   ExpectScriptTrue("result.a === result.b");
1478 
1479   // RegExp containing a Latin-1 string.
1480   value = DecodeTest(
1481       {0xFF, 0x0C, 0x52, 0x22, 0x06, 'Q', 'u', 0xE9, 'b', 'e', 'c', 0x02});
1482   ASSERT_TRUE(value->IsRegExp());
1483   ExpectScriptTrue("result.toString() === '/Qu\\xe9bec/i'");
1484 }
1485 
1486 // Tests that invalid flags are not accepted by the deserializer.
TEST_F(ValueSerializerTest,DecodeRegExpDotAll)1487 TEST_F(ValueSerializerTest, DecodeRegExpDotAll) {
1488   Local<Value> value =
1489       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x52, 0x03, 0x66, 0x6F, 0x6F, 0x1F});
1490   ASSERT_TRUE(value->IsRegExp());
1491   ExpectScriptTrue("Object.getPrototypeOf(result) === RegExp.prototype");
1492   ExpectScriptTrue("result.toString() === '/foo/gimuy'");
1493 
1494   value =
1495       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x52, 0x03, 0x66, 0x6F, 0x6F, 0x3F});
1496   ASSERT_TRUE(value->IsRegExp());
1497   ExpectScriptTrue("Object.getPrototypeOf(result) === RegExp.prototype");
1498   ExpectScriptTrue("result.toString() === '/foo/gimsuy'");
1499 
1500   InvalidDecodeTest(
1501       {0xFF, 0x09, 0x3F, 0x00, 0x52, 0x03, 0x66, 0x6F, 0x6F, 0xFF});
1502 }
1503 
TEST_F(ValueSerializerTest,DecodeLinearRegExp)1504 TEST_F(ValueSerializerTest, DecodeLinearRegExp) {
1505   bool flag_was_enabled = i::FLAG_enable_experimental_regexp_engine;
1506 
1507   // The last byte encodes the regexp flags.
1508   std::vector<uint8_t> regexp_encoding = {0xFF, 0x09, 0x3F, 0x00, 0x52,
1509                                           0x03, 0x66, 0x6F, 0x6F, 0x6D};
1510 
1511   i::FLAG_enable_experimental_regexp_engine = true;
1512   Local<Value> value = DecodeTest(regexp_encoding);
1513   ASSERT_TRUE(value->IsRegExp());
1514   ExpectScriptTrue("Object.getPrototypeOf(result) === RegExp.prototype");
1515   ExpectScriptTrue("result.toString() === '/foo/glmsy'");
1516 
1517   i::FLAG_enable_experimental_regexp_engine = false;
1518   InvalidDecodeTest(regexp_encoding);
1519 
1520   i::FLAG_enable_experimental_regexp_engine = flag_was_enabled;
1521 }
1522 
TEST_F(ValueSerializerTest,DecodeHasIndicesRegExp)1523 TEST_F(ValueSerializerTest, DecodeHasIndicesRegExp) {
1524   // The last byte encodes the regexp flags.
1525   std::vector<uint8_t> regexp_encoding = {0xFF, 0x09, 0x3F, 0x00, 0x52, 0x03,
1526                                           0x66, 0x6F, 0x6F, 0xAD, 0x01};
1527 
1528   Local<Value> value = DecodeTest(regexp_encoding);
1529   ASSERT_TRUE(value->IsRegExp());
1530   ExpectScriptTrue("Object.getPrototypeOf(result) === RegExp.prototype");
1531   ExpectScriptTrue("result.toString() === '/foo/dgmsy'");
1532 }
1533 
TEST_F(ValueSerializerTest,RoundTripMap)1534 TEST_F(ValueSerializerTest, RoundTripMap) {
1535   Local<Value> value = RoundTripTest("var m = new Map(); m.set(42, 'foo'); m;");
1536   ASSERT_TRUE(value->IsMap());
1537   ExpectScriptTrue("Object.getPrototypeOf(result) === Map.prototype");
1538   ExpectScriptTrue("result.size === 1");
1539   ExpectScriptTrue("result.get(42) === 'foo'");
1540 
1541   value = RoundTripTest("var m = new Map(); m.set(m, m); m;");
1542   ASSERT_TRUE(value->IsMap());
1543   ExpectScriptTrue("result.size === 1");
1544   ExpectScriptTrue("result.get(result) === result");
1545 
1546   // Iteration order must be preserved.
1547   value = RoundTripTest(
1548       "var m = new Map();"
1549       "m.set(1, 0); m.set('a', 0); m.set(3, 0); m.set(2, 0);"
1550       "m;");
1551   ASSERT_TRUE(value->IsMap());
1552   ExpectScriptTrue("Array.from(result.keys()).toString() === '1,a,3,2'");
1553 }
1554 
TEST_F(ValueSerializerTest,DecodeMap)1555 TEST_F(ValueSerializerTest, DecodeMap) {
1556   Local<Value> value =
1557       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3B, 0x3F, 0x01, 0x49, 0x54, 0x3F,
1558                   0x01, 0x53, 0x03, 0x66, 0x6F, 0x6F, 0x3A, 0x02});
1559   ASSERT_TRUE(value->IsMap());
1560   ExpectScriptTrue("Object.getPrototypeOf(result) === Map.prototype");
1561   ExpectScriptTrue("result.size === 1");
1562   ExpectScriptTrue("result.get(42) === 'foo'");
1563 
1564   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3B, 0x3F, 0x01, 0x5E, 0x00,
1565                       0x3F, 0x01, 0x5E, 0x00, 0x3A, 0x02, 0x00});
1566   ASSERT_TRUE(value->IsMap());
1567   ExpectScriptTrue("result.size === 1");
1568   ExpectScriptTrue("result.get(result) === result");
1569 
1570   // Iteration order must be preserved.
1571   value =
1572       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3B, 0x3F, 0x01, 0x49, 0x02, 0x3F,
1573                   0x01, 0x49, 0x00, 0x3F, 0x01, 0x53, 0x01, 0x61, 0x3F, 0x01,
1574                   0x49, 0x00, 0x3F, 0x01, 0x49, 0x06, 0x3F, 0x01, 0x49, 0x00,
1575                   0x3F, 0x01, 0x49, 0x04, 0x3F, 0x01, 0x49, 0x00, 0x3A, 0x08});
1576   ASSERT_TRUE(value->IsMap());
1577   ExpectScriptTrue("Array.from(result.keys()).toString() === '1,a,3,2'");
1578 }
1579 
TEST_F(ValueSerializerTest,RoundTripMapWithTrickyGetters)1580 TEST_F(ValueSerializerTest, RoundTripMapWithTrickyGetters) {
1581   // Even if an entry is removed or reassigned, the original key/value pair is
1582   // used.
1583   Local<Value> value = RoundTripTest(
1584       "var m = new Map();"
1585       "m.set(0, { get a() {"
1586       "  m.delete(1); m.set(2, 'baz'); m.set(3, 'quux');"
1587       "}});"
1588       "m.set(1, 'foo');"
1589       "m.set(2, 'bar');"
1590       "m;");
1591   ASSERT_TRUE(value->IsMap());
1592   ExpectScriptTrue("Array.from(result.keys()).toString() === '0,1,2'");
1593   ExpectScriptTrue("result.get(1) === 'foo'");
1594   ExpectScriptTrue("result.get(2) === 'bar'");
1595 
1596   // However, deeper modifications of objects yet to be serialized still apply.
1597   value = RoundTripTest(
1598       "var m = new Map();"
1599       "var key = { get a() { value.foo = 'bar'; } };"
1600       "var value = { get a() { key.baz = 'quux'; } };"
1601       "m.set(key, value);"
1602       "m;");
1603   ASSERT_TRUE(value->IsMap());
1604   ExpectScriptTrue("!('baz' in Array.from(result.keys())[0])");
1605   ExpectScriptTrue("Array.from(result.values())[0].foo === 'bar'");
1606 }
1607 
TEST_F(ValueSerializerTest,RoundTripSet)1608 TEST_F(ValueSerializerTest, RoundTripSet) {
1609   Local<Value> value =
1610       RoundTripTest("var s = new Set(); s.add(42); s.add('foo'); s;");
1611   ASSERT_TRUE(value->IsSet());
1612   ExpectScriptTrue("Object.getPrototypeOf(result) === Set.prototype");
1613   ExpectScriptTrue("result.size === 2");
1614   ExpectScriptTrue("result.has(42)");
1615   ExpectScriptTrue("result.has('foo')");
1616 
1617   value = RoundTripTest("var s = new Set(); s.add(s); s;");
1618   ASSERT_TRUE(value->IsSet());
1619   ExpectScriptTrue("result.size === 1");
1620   ExpectScriptTrue("result.has(result)");
1621 
1622   // Iteration order must be preserved.
1623   value = RoundTripTest(
1624       "var s = new Set();"
1625       "s.add(1); s.add('a'); s.add(3); s.add(2);"
1626       "s;");
1627   ASSERT_TRUE(value->IsSet());
1628   ExpectScriptTrue("Array.from(result.keys()).toString() === '1,a,3,2'");
1629 }
1630 
TEST_F(ValueSerializerTest,DecodeSet)1631 TEST_F(ValueSerializerTest, DecodeSet) {
1632   Local<Value> value =
1633       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x27, 0x3F, 0x01, 0x49, 0x54, 0x3F,
1634                   0x01, 0x53, 0x03, 0x66, 0x6F, 0x6F, 0x2C, 0x02});
1635   ASSERT_TRUE(value->IsSet());
1636   ExpectScriptTrue("Object.getPrototypeOf(result) === Set.prototype");
1637   ExpectScriptTrue("result.size === 2");
1638   ExpectScriptTrue("result.has(42)");
1639   ExpectScriptTrue("result.has('foo')");
1640 
1641   value = DecodeTest(
1642       {0xFF, 0x09, 0x3F, 0x00, 0x27, 0x3F, 0x01, 0x5E, 0x00, 0x2C, 0x01, 0x00});
1643   ASSERT_TRUE(value->IsSet());
1644   ExpectScriptTrue("result.size === 1");
1645   ExpectScriptTrue("result.has(result)");
1646 
1647   // Iteration order must be preserved.
1648   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x27, 0x3F, 0x01, 0x49,
1649                       0x02, 0x3F, 0x01, 0x53, 0x01, 0x61, 0x3F, 0x01,
1650                       0x49, 0x06, 0x3F, 0x01, 0x49, 0x04, 0x2C, 0x04});
1651   ASSERT_TRUE(value->IsSet());
1652   ExpectScriptTrue("Array.from(result.keys()).toString() === '1,a,3,2'");
1653 }
1654 
TEST_F(ValueSerializerTest,RoundTripSetWithTrickyGetters)1655 TEST_F(ValueSerializerTest, RoundTripSetWithTrickyGetters) {
1656   // Even if an element is added or removed during serialization, the original
1657   // set of elements is used.
1658   Local<Value> value = RoundTripTest(
1659       "var s = new Set();"
1660       "s.add({ get a() { s.delete(1); s.add(2); } });"
1661       "s.add(1);"
1662       "s;");
1663   ASSERT_TRUE(value->IsSet());
1664   ExpectScriptTrue(
1665       "Array.from(result.keys()).toString() === '[object Object],1'");
1666 
1667   // However, deeper modifications of objects yet to be serialized still apply.
1668   value = RoundTripTest(
1669       "var s = new Set();"
1670       "var first = { get a() { second.foo = 'bar'; } };"
1671       "var second = { get a() { first.baz = 'quux'; } };"
1672       "s.add(first);"
1673       "s.add(second);"
1674       "s;");
1675   ASSERT_TRUE(value->IsSet());
1676   ExpectScriptTrue("!('baz' in Array.from(result.keys())[0])");
1677   ExpectScriptTrue("Array.from(result.keys())[1].foo === 'bar'");
1678 }
1679 
TEST_F(ValueSerializerTest,RoundTripArrayBuffer)1680 TEST_F(ValueSerializerTest, RoundTripArrayBuffer) {
1681   Local<Value> value = RoundTripTest("new ArrayBuffer()");
1682   ASSERT_TRUE(value->IsArrayBuffer());
1683   EXPECT_EQ(0u, ArrayBuffer::Cast(*value)->ByteLength());
1684   ExpectScriptTrue("Object.getPrototypeOf(result) === ArrayBuffer.prototype");
1685 
1686   value = RoundTripTest("new Uint8Array([0, 128, 255]).buffer");
1687   ASSERT_TRUE(value->IsArrayBuffer());
1688   EXPECT_EQ(3u, ArrayBuffer::Cast(*value)->ByteLength());
1689   ExpectScriptTrue("new Uint8Array(result).toString() === '0,128,255'");
1690 
1691   value =
1692       RoundTripTest("({ a: new ArrayBuffer(), get b() { return this.a; }})");
1693   ExpectScriptTrue("result.a instanceof ArrayBuffer");
1694   ExpectScriptTrue("result.a === result.b");
1695 }
1696 
TEST_F(ValueSerializerTest,DecodeArrayBuffer)1697 TEST_F(ValueSerializerTest, DecodeArrayBuffer) {
1698   Local<Value> value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x42, 0x00});
1699   ASSERT_TRUE(value->IsArrayBuffer());
1700   EXPECT_EQ(0u, ArrayBuffer::Cast(*value)->ByteLength());
1701   ExpectScriptTrue("Object.getPrototypeOf(result) === ArrayBuffer.prototype");
1702 
1703   value =
1704       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x42, 0x03, 0x00, 0x80, 0xFF, 0x00});
1705   ASSERT_TRUE(value->IsArrayBuffer());
1706   EXPECT_EQ(3u, ArrayBuffer::Cast(*value)->ByteLength());
1707   ExpectScriptTrue("new Uint8Array(result).toString() === '0,128,255'");
1708 
1709   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x01,
1710                       0x61, 0x3F, 0x01, 0x42, 0x00, 0x3F, 0x02, 0x53, 0x01,
1711                       0x62, 0x3F, 0x02, 0x5E, 0x01, 0x7B, 0x02, 0x00});
1712   ExpectScriptTrue("result.a instanceof ArrayBuffer");
1713   ExpectScriptTrue("result.a === result.b");
1714 }
1715 
TEST_F(ValueSerializerTest,DecodeInvalidArrayBuffer)1716 TEST_F(ValueSerializerTest, DecodeInvalidArrayBuffer) {
1717   InvalidDecodeTest({0xFF, 0x09, 0x42, 0xFF, 0xFF, 0x00});
1718 }
1719 
1720 // An array buffer allocator that never has available memory.
1721 class OOMArrayBufferAllocator : public ArrayBuffer::Allocator {
1722  public:
Allocate(size_t)1723   void* Allocate(size_t) override { return nullptr; }
AllocateUninitialized(size_t)1724   void* AllocateUninitialized(size_t) override { return nullptr; }
Free(void *,size_t)1725   void Free(void*, size_t) override {}
1726 };
1727 
TEST_F(ValueSerializerTest,DecodeArrayBufferOOM)1728 TEST_F(ValueSerializerTest, DecodeArrayBufferOOM) {
1729   // This test uses less of the harness, because it has to customize the
1730   // isolate.
1731   OOMArrayBufferAllocator allocator;
1732   Isolate::CreateParams params;
1733   params.array_buffer_allocator = &allocator;
1734   Isolate* isolate = Isolate::New(params);
1735   {
1736     Isolate::Scope isolate_scope(isolate);
1737     HandleScope handle_scope(isolate);
1738     Local<Context> context = Context::New(isolate);
1739     Context::Scope context_scope(context);
1740     TryCatch try_catch(isolate);
1741 
1742     const std::vector<uint8_t> data = {0xFF, 0x09, 0x3F, 0x00, 0x42,
1743                                        0x03, 0x00, 0x80, 0xFF, 0x00};
1744     ValueDeserializer deserializer(isolate, &data[0],
1745                                    static_cast<int>(data.size()), nullptr);
1746     deserializer.SetSupportsLegacyWireFormat(true);
1747     ASSERT_TRUE(deserializer.ReadHeader(context).FromMaybe(false));
1748     ASSERT_FALSE(try_catch.HasCaught());
1749     EXPECT_TRUE(deserializer.ReadValue(context).IsEmpty());
1750     EXPECT_TRUE(try_catch.HasCaught());
1751   }
1752   isolate->Dispose();
1753 }
1754 
1755 // Includes an ArrayBuffer wrapper marked for transfer from the serialization
1756 // context to the deserialization context.
1757 class ValueSerializerTestWithArrayBufferTransfer : public ValueSerializerTest {
1758  protected:
1759   static const size_t kTestByteLength = 4;
1760 
ValueSerializerTestWithArrayBufferTransfer()1761   ValueSerializerTestWithArrayBufferTransfer() {
1762     {
1763       Context::Scope scope(serialization_context());
1764       input_buffer_ = ArrayBuffer::New(isolate(), 0);
1765     }
1766     {
1767       Context::Scope scope(deserialization_context());
1768       output_buffer_ = ArrayBuffer::New(isolate(), kTestByteLength);
1769       const uint8_t data[kTestByteLength] = {0x00, 0x01, 0x80, 0xFF};
1770       memcpy(output_buffer_->GetBackingStore()->Data(), data, kTestByteLength);
1771     }
1772   }
1773 
input_buffer()1774   const Local<ArrayBuffer>& input_buffer() { return input_buffer_; }
output_buffer()1775   const Local<ArrayBuffer>& output_buffer() { return output_buffer_; }
1776 
BeforeEncode(ValueSerializer * serializer)1777   void BeforeEncode(ValueSerializer* serializer) override {
1778     serializer->TransferArrayBuffer(0, input_buffer_);
1779   }
1780 
BeforeDecode(ValueDeserializer * deserializer)1781   void BeforeDecode(ValueDeserializer* deserializer) override {
1782     deserializer->TransferArrayBuffer(0, output_buffer_);
1783   }
1784 
1785  private:
1786   Local<ArrayBuffer> input_buffer_;
1787   Local<ArrayBuffer> output_buffer_;
1788 };
1789 
TEST_F(ValueSerializerTestWithArrayBufferTransfer,RoundTripArrayBufferTransfer)1790 TEST_F(ValueSerializerTestWithArrayBufferTransfer,
1791        RoundTripArrayBufferTransfer) {
1792   Local<Value> value = RoundTripTest(input_buffer());
1793   ASSERT_TRUE(value->IsArrayBuffer());
1794   EXPECT_EQ(output_buffer(), value);
1795   ExpectScriptTrue("new Uint8Array(result).toString() === '0,1,128,255'");
1796 
1797   Local<Object> object;
1798   {
1799     Context::Scope scope(serialization_context());
1800     object = Object::New(isolate());
1801     EXPECT_TRUE(object
1802                     ->CreateDataProperty(serialization_context(),
1803                                          StringFromUtf8("a"), input_buffer())
1804                     .FromMaybe(false));
1805     EXPECT_TRUE(object
1806                     ->CreateDataProperty(serialization_context(),
1807                                          StringFromUtf8("b"), input_buffer())
1808                     .FromMaybe(false));
1809   }
1810   value = RoundTripTest(object);
1811   ExpectScriptTrue("result.a instanceof ArrayBuffer");
1812   ExpectScriptTrue("result.a === result.b");
1813   ExpectScriptTrue("new Uint8Array(result.a).toString() === '0,1,128,255'");
1814 }
1815 
TEST_F(ValueSerializerTest,RoundTripTypedArray)1816 TEST_F(ValueSerializerTest, RoundTripTypedArray) {
1817   // Check that the right type comes out the other side for every kind of typed
1818   // array.
1819   Local<Value> value;
1820 #define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype)             \
1821   value = RoundTripTest("new " #Type "Array(2)");                        \
1822   ASSERT_TRUE(value->Is##Type##Array());                                 \
1823   EXPECT_EQ(2u * sizeof(ctype), TypedArray::Cast(*value)->ByteLength()); \
1824   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());                     \
1825   ExpectScriptTrue("Object.getPrototypeOf(result) === " #Type            \
1826                    "Array.prototype");
1827 
1828   TYPED_ARRAYS(TYPED_ARRAY_ROUND_TRIP_TEST)
1829 #undef TYPED_ARRAY_ROUND_TRIP_TEST
1830 
1831   // Check that values of various kinds are suitably preserved.
1832   value = RoundTripTest("new Uint8Array([1, 128, 255])");
1833   ExpectScriptTrue("result.toString() === '1,128,255'");
1834 
1835   value = RoundTripTest("new Int16Array([0, 256, -32768])");
1836   ExpectScriptTrue("result.toString() === '0,256,-32768'");
1837 
1838   value = RoundTripTest("new Float32Array([0, -0.5, NaN, Infinity])");
1839   ExpectScriptTrue("result.toString() === '0,-0.5,NaN,Infinity'");
1840 
1841   // Array buffer views sharing a buffer should do so on the other side.
1842   // Similarly, multiple references to the same typed array should be resolved.
1843   value = RoundTripTest(
1844       "var buffer = new ArrayBuffer(32);"
1845       "({"
1846       "  u8: new Uint8Array(buffer),"
1847       "  get u8_2() { return this.u8; },"
1848       "  f32: new Float32Array(buffer, 4, 5),"
1849       "  b: buffer,"
1850       "});");
1851   ExpectScriptTrue("result.u8 instanceof Uint8Array");
1852   ExpectScriptTrue("result.u8 === result.u8_2");
1853   ExpectScriptTrue("result.f32 instanceof Float32Array");
1854   ExpectScriptTrue("result.u8.buffer === result.f32.buffer");
1855   ExpectScriptTrue("result.f32.byteOffset === 4");
1856   ExpectScriptTrue("result.f32.length === 5");
1857 }
1858 
TEST_F(ValueSerializerTest,DecodeTypedArray)1859 TEST_F(ValueSerializerTest, DecodeTypedArray) {
1860   // Check that the right type comes out the other side for every kind of typed
1861   // array.
1862   Local<Value> value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42,
1863                                    0x02, 0x00, 0x00, 0x56, 0x42, 0x00, 0x02});
1864   ASSERT_TRUE(value->IsUint8Array());
1865   EXPECT_EQ(2u, TypedArray::Cast(*value)->ByteLength());
1866   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1867   ExpectScriptTrue("Object.getPrototypeOf(result) === Uint8Array.prototype");
1868 
1869   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x02, 0x00,
1870                       0x00, 0x56, 0x62, 0x00, 0x02});
1871   ASSERT_TRUE(value->IsInt8Array());
1872   EXPECT_EQ(2u, TypedArray::Cast(*value)->ByteLength());
1873   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1874   ExpectScriptTrue("Object.getPrototypeOf(result) === Int8Array.prototype");
1875 
1876 #if defined(V8_TARGET_LITTLE_ENDIAN)
1877   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x04, 0x00,
1878                       0x00, 0x00, 0x00, 0x56, 0x57, 0x00, 0x04});
1879   ASSERT_TRUE(value->IsUint16Array());
1880   EXPECT_EQ(4u, TypedArray::Cast(*value)->ByteLength());
1881   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1882   ExpectScriptTrue("Object.getPrototypeOf(result) === Uint16Array.prototype");
1883 
1884   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x04, 0x00,
1885                       0x00, 0x00, 0x00, 0x56, 0x77, 0x00, 0x04});
1886   ASSERT_TRUE(value->IsInt16Array());
1887   EXPECT_EQ(4u, TypedArray::Cast(*value)->ByteLength());
1888   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1889   ExpectScriptTrue("Object.getPrototypeOf(result) === Int16Array.prototype");
1890 
1891   value =
1892       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x08, 0x00, 0x00,
1893                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x44, 0x00, 0x08});
1894   ASSERT_TRUE(value->IsUint32Array());
1895   EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength());
1896   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1897   ExpectScriptTrue("Object.getPrototypeOf(result) === Uint32Array.prototype");
1898 
1899   value =
1900       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x08, 0x00, 0x00,
1901                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x64, 0x00, 0x08});
1902   ASSERT_TRUE(value->IsInt32Array());
1903   EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength());
1904   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1905   ExpectScriptTrue("Object.getPrototypeOf(result) === Int32Array.prototype");
1906 
1907   value =
1908       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x08, 0x00, 0x00,
1909                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x66, 0x00, 0x08});
1910   ASSERT_TRUE(value->IsFloat32Array());
1911   EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength());
1912   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1913   ExpectScriptTrue("Object.getPrototypeOf(result) === Float32Array.prototype");
1914 
1915   value =
1916       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x10, 0x00, 0x00,
1917                   0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1918                   0x00, 0x00, 0x00, 0x00, 0x56, 0x46, 0x00, 0x10});
1919   ASSERT_TRUE(value->IsFloat64Array());
1920   EXPECT_EQ(16u, TypedArray::Cast(*value)->ByteLength());
1921   EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
1922   ExpectScriptTrue("Object.getPrototypeOf(result) === Float64Array.prototype");
1923 
1924 #endif  // V8_TARGET_LITTLE_ENDIAN
1925 
1926   // Check that values of various kinds are suitably preserved.
1927   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x03, 0x01,
1928                       0x80, 0xFF, 0x56, 0x42, 0x00, 0x03, 0x00});
1929   ExpectScriptTrue("result.toString() === '1,128,255'");
1930 
1931 #if defined(V8_TARGET_LITTLE_ENDIAN)
1932   value = DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x06, 0x00,
1933                       0x00, 0x00, 0x01, 0x00, 0x80, 0x56, 0x77, 0x00, 0x06});
1934   ExpectScriptTrue("result.toString() === '0,256,-32768'");
1935 
1936   value =
1937       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x10, 0x00, 0x00,
1938                   0x00, 0x00, 0x00, 0x00, 0x00, 0xBF, 0x00, 0x00, 0xC0, 0x7F,
1939                   0x00, 0x00, 0x80, 0x7F, 0x56, 0x66, 0x00, 0x10});
1940   ExpectScriptTrue("result.toString() === '0,-0.5,NaN,Infinity'");
1941 
1942 #endif  // V8_TARGET_LITTLE_ENDIAN
1943 
1944   // Array buffer views sharing a buffer should do so on the other side.
1945   // Similarly, multiple references to the same typed array should be resolved.
1946   value = DecodeTest(
1947       {0xFF, 0x09, 0x3F, 0x00, 0x6F, 0x3F, 0x01, 0x53, 0x02, 0x75, 0x38, 0x3F,
1948        0x01, 0x3F, 0x01, 0x42, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1949        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1950        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1951        0x00, 0x56, 0x42, 0x00, 0x20, 0x3F, 0x03, 0x53, 0x04, 0x75, 0x38, 0x5F,
1952        0x32, 0x3F, 0x03, 0x5E, 0x02, 0x3F, 0x03, 0x53, 0x03, 0x66, 0x33, 0x32,
1953        0x3F, 0x03, 0x3F, 0x03, 0x5E, 0x01, 0x56, 0x66, 0x04, 0x14, 0x3F, 0x04,
1954        0x53, 0x01, 0x62, 0x3F, 0x04, 0x5E, 0x01, 0x7B, 0x04, 0x00});
1955   ExpectScriptTrue("result.u8 instanceof Uint8Array");
1956   ExpectScriptTrue("result.u8 === result.u8_2");
1957   ExpectScriptTrue("result.f32 instanceof Float32Array");
1958   ExpectScriptTrue("result.u8.buffer === result.f32.buffer");
1959   ExpectScriptTrue("result.f32.byteOffset === 4");
1960   ExpectScriptTrue("result.f32.length === 5");
1961 }
1962 
TEST_F(ValueSerializerTest,DecodeInvalidTypedArray)1963 TEST_F(ValueSerializerTest, DecodeInvalidTypedArray) {
1964   // Byte offset out of range.
1965   InvalidDecodeTest(
1966       {0xFF, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0x42, 0x03, 0x01});
1967   // Byte offset in range, offset + length out of range.
1968   InvalidDecodeTest(
1969       {0xFF, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0x42, 0x01, 0x03});
1970   // Byte offset not divisible by element size.
1971   InvalidDecodeTest(
1972       {0xFF, 0x09, 0x42, 0x04, 0x00, 0x00, 0x00, 0x00, 0x56, 0x77, 0x01, 0x02});
1973   // Byte length not divisible by element size.
1974   InvalidDecodeTest(
1975       {0xFF, 0x09, 0x42, 0x04, 0x00, 0x00, 0x00, 0x00, 0x56, 0x77, 0x02, 0x01});
1976   // Invalid view type (0xFF).
1977   InvalidDecodeTest(
1978       {0xFF, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0xFF, 0x01, 0x01});
1979 }
1980 
TEST_F(ValueSerializerTest,RoundTripDataView)1981 TEST_F(ValueSerializerTest, RoundTripDataView) {
1982   Local<Value> value = RoundTripTest("new DataView(new ArrayBuffer(4), 1, 2)");
1983   ASSERT_TRUE(value->IsDataView());
1984   EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset());
1985   EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength());
1986   EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength());
1987   ExpectScriptTrue("Object.getPrototypeOf(result) === DataView.prototype");
1988 }
1989 
TEST_F(ValueSerializerTest,DecodeDataView)1990 TEST_F(ValueSerializerTest, DecodeDataView) {
1991   Local<Value> value =
1992       DecodeTest({0xFF, 0x09, 0x3F, 0x00, 0x3F, 0x00, 0x42, 0x04, 0x00, 0x00,
1993                   0x00, 0x00, 0x56, 0x3F, 0x01, 0x02});
1994   ASSERT_TRUE(value->IsDataView());
1995   EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset());
1996   EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength());
1997   EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength());
1998   ExpectScriptTrue("Object.getPrototypeOf(result) === DataView.prototype");
1999 }
2000 
TEST_F(ValueSerializerTest,DecodeArrayWithLengthProperty1)2001 TEST_F(ValueSerializerTest, DecodeArrayWithLengthProperty1) {
2002   InvalidDecodeTest({0xff, 0x0d, 0x41, 0x03, 0x49, 0x02, 0x49, 0x04,
2003                      0x49, 0x06, 0x22, 0x06, 0x6c, 0x65, 0x6e, 0x67,
2004                      0x74, 0x68, 0x49, 0x02, 0x24, 0x01, 0x03});
2005 }
2006 
TEST_F(ValueSerializerTest,DecodeArrayWithLengthProperty2)2007 TEST_F(ValueSerializerTest, DecodeArrayWithLengthProperty2) {
2008   InvalidDecodeTest({0xff, 0x0d, 0x41, 0x03, 0x49, 0x02, 0x49, 0x04,
2009                      0x49, 0x06, 0x22, 0x06, 0x6c, 0x65, 0x6e, 0x67,
2010                      0x74, 0x68, 0x6f, 0x7b, 0x00, 0x24, 0x01, 0x03});
2011 }
2012 
TEST_F(ValueSerializerTest,DecodeInvalidDataView)2013 TEST_F(ValueSerializerTest, DecodeInvalidDataView) {
2014   // Byte offset out of range.
2015   InvalidDecodeTest(
2016       {0xFF, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0x3F, 0x03, 0x01});
2017   // Byte offset in range, offset + length out of range.
2018   InvalidDecodeTest(
2019       {0xFF, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0x3F, 0x01, 0x03});
2020 }
2021 
2022 class ValueSerializerTestWithSharedArrayBufferClone
2023     : public ValueSerializerTest {
2024  protected:
ValueSerializerTestWithSharedArrayBufferClone()2025   ValueSerializerTestWithSharedArrayBufferClone()
2026       : serializer_delegate_(this), deserializer_delegate_(this) {}
2027 
InitializeData(const std::vector<uint8_t> & data,bool is_wasm_memory)2028   void InitializeData(const std::vector<uint8_t>& data, bool is_wasm_memory) {
2029     data_ = data;
2030     {
2031       Context::Scope scope(serialization_context());
2032       input_buffer_ =
2033           NewSharedArrayBuffer(data_.data(), data_.size(), is_wasm_memory);
2034     }
2035     {
2036       Context::Scope scope(deserialization_context());
2037       output_buffer_ =
2038           NewSharedArrayBuffer(data_.data(), data_.size(), is_wasm_memory);
2039     }
2040   }
2041 
input_buffer()2042   const Local<SharedArrayBuffer>& input_buffer() { return input_buffer_; }
output_buffer()2043   const Local<SharedArrayBuffer>& output_buffer() { return output_buffer_; }
2044 
NewSharedArrayBuffer(void * data,size_t byte_length,bool is_wasm_memory)2045   Local<SharedArrayBuffer> NewSharedArrayBuffer(void* data, size_t byte_length,
2046                                                 bool is_wasm_memory) {
2047 #if V8_ENABLE_WEBASSEMBLY
2048     if (is_wasm_memory) {
2049       // TODO(titzer): there is no way to create Wasm memory backing stores
2050       // through the API, or to create a shared array buffer whose backing
2051       // store is wasm memory, so use the internal API.
2052       DCHECK_EQ(0, byte_length % i::wasm::kWasmPageSize);
2053       auto pages = byte_length / i::wasm::kWasmPageSize;
2054       auto i_isolate = reinterpret_cast<i::Isolate*>(isolate());
2055       auto backing_store = i::BackingStore::AllocateWasmMemory(
2056           i_isolate, pages, pages, i::SharedFlag::kShared);
2057       memcpy(backing_store->buffer_start(), data, byte_length);
2058       i::Handle<i::JSArrayBuffer> buffer =
2059           i_isolate->factory()->NewJSSharedArrayBuffer(
2060               std::move(backing_store));
2061       return Utils::ToLocalShared(buffer);
2062     }
2063 #endif  // V8_ENABLE_WEBASSEMBLY
2064 
2065     CHECK(!is_wasm_memory);
2066     auto sab = SharedArrayBuffer::New(isolate(), byte_length);
2067     memcpy(sab->GetBackingStore()->Data(), data, byte_length);
2068     return sab;
2069   }
2070 
SetUpTestCase()2071   static void SetUpTestCase() {
2072     flag_was_enabled_ = i::FLAG_harmony_sharedarraybuffer;
2073     i::FLAG_harmony_sharedarraybuffer = true;
2074     ValueSerializerTest::SetUpTestCase();
2075   }
2076 
TearDownTestCase()2077   static void TearDownTestCase() {
2078     ValueSerializerTest::TearDownTestCase();
2079     i::FLAG_harmony_sharedarraybuffer = flag_was_enabled_;
2080     flag_was_enabled_ = false;
2081   }
2082 
2083  protected:
2084 // GMock doesn't use the "override" keyword.
2085 #if __clang__
2086 #pragma clang diagnostic push
2087 #pragma clang diagnostic ignored "-Winconsistent-missing-override"
2088 #endif
2089 
2090   class SerializerDelegate : public ValueSerializer::Delegate {
2091    public:
SerializerDelegate(ValueSerializerTestWithSharedArrayBufferClone * test)2092     explicit SerializerDelegate(
2093         ValueSerializerTestWithSharedArrayBufferClone* test)
2094         : test_(test) {}
2095     MOCK_METHOD(Maybe<uint32_t>, GetSharedArrayBufferId,
2096                 (Isolate*, Local<SharedArrayBuffer> shared_array_buffer),
2097                 (override));
2098     MOCK_METHOD(MaybeLocal<SharedArrayBuffer>, GetSharedArrayBufferFromId,
2099                 (Isolate*, uint32_t id));
ThrowDataCloneError(Local<String> message)2100     void ThrowDataCloneError(Local<String> message) override {
2101       test_->isolate()->ThrowException(Exception::Error(message));
2102     }
2103 
2104    private:
2105     ValueSerializerTestWithSharedArrayBufferClone* test_;
2106   };
2107 
2108   class DeserializerDelegate : public ValueDeserializer::Delegate {
2109    public:
DeserializerDelegate(ValueSerializerTestWithSharedArrayBufferClone * test)2110     explicit DeserializerDelegate(
2111         ValueSerializerTestWithSharedArrayBufferClone* test) {}
2112     MOCK_METHOD(MaybeLocal<SharedArrayBuffer>, GetSharedArrayBufferFromId,
2113                 (Isolate*, uint32_t id), (override));
2114   };
2115 
2116 #if __clang__
2117 #pragma clang diagnostic pop
2118 #endif
2119 
GetSerializerDelegate()2120   ValueSerializer::Delegate* GetSerializerDelegate() override {
2121     return &serializer_delegate_;
2122   }
2123 
GetDeserializerDelegate()2124   ValueDeserializer::Delegate* GetDeserializerDelegate() override {
2125     return &deserializer_delegate_;
2126   }
2127 
2128   SerializerDelegate serializer_delegate_;
2129   DeserializerDelegate deserializer_delegate_;
2130 
2131  private:
2132   static bool flag_was_enabled_;
2133   std::vector<uint8_t> data_;
2134   Local<SharedArrayBuffer> input_buffer_;
2135   Local<SharedArrayBuffer> output_buffer_;
2136 };
2137 
2138 bool ValueSerializerTestWithSharedArrayBufferClone::flag_was_enabled_ = false;
2139 
TEST_F(ValueSerializerTestWithSharedArrayBufferClone,RoundTripSharedArrayBufferClone)2140 TEST_F(ValueSerializerTestWithSharedArrayBufferClone,
2141        RoundTripSharedArrayBufferClone) {
2142   InitializeData({0x00, 0x01, 0x80, 0xFF}, false);
2143 
2144   EXPECT_CALL(serializer_delegate_,
2145               GetSharedArrayBufferId(isolate(), input_buffer()))
2146       .WillRepeatedly(Return(Just(0U)));
2147   EXPECT_CALL(deserializer_delegate_, GetSharedArrayBufferFromId(isolate(), 0U))
2148       .WillRepeatedly(Return(output_buffer()));
2149 
2150   Local<Value> value = RoundTripTest(input_buffer());
2151   ASSERT_TRUE(value->IsSharedArrayBuffer());
2152   EXPECT_EQ(output_buffer(), value);
2153   ExpectScriptTrue("new Uint8Array(result).toString() === '0,1,128,255'");
2154 
2155   Local<Object> object;
2156   {
2157     Context::Scope scope(serialization_context());
2158     object = Object::New(isolate());
2159     EXPECT_TRUE(object
2160                     ->CreateDataProperty(serialization_context(),
2161                                          StringFromUtf8("a"), input_buffer())
2162                     .FromMaybe(false));
2163     EXPECT_TRUE(object
2164                     ->CreateDataProperty(serialization_context(),
2165                                          StringFromUtf8("b"), input_buffer())
2166                     .FromMaybe(false));
2167   }
2168   value = RoundTripTest(object);
2169   ExpectScriptTrue("result.a instanceof SharedArrayBuffer");
2170   ExpectScriptTrue("result.a === result.b");
2171   ExpectScriptTrue("new Uint8Array(result.a).toString() === '0,1,128,255'");
2172 }
2173 
2174 #if V8_ENABLE_WEBASSEMBLY
TEST_F(ValueSerializerTestWithSharedArrayBufferClone,RoundTripWebAssemblyMemory)2175 TEST_F(ValueSerializerTestWithSharedArrayBufferClone,
2176        RoundTripWebAssemblyMemory) {
2177   bool flag_was_enabled = i::FLAG_experimental_wasm_threads;
2178   i::FLAG_experimental_wasm_threads = true;
2179 
2180   std::vector<uint8_t> data = {0x00, 0x01, 0x80, 0xFF};
2181   data.resize(65536);
2182   InitializeData(data, true);
2183 
2184   EXPECT_CALL(serializer_delegate_,
2185               GetSharedArrayBufferId(isolate(), input_buffer()))
2186       .WillRepeatedly(Return(Just(0U)));
2187   EXPECT_CALL(deserializer_delegate_, GetSharedArrayBufferFromId(isolate(), 0U))
2188       .WillRepeatedly(Return(output_buffer()));
2189 
2190   Local<Value> input;
2191   {
2192     Context::Scope scope(serialization_context());
2193     const int32_t kMaxPages = 1;
2194     i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate());
2195     i::Handle<i::JSArrayBuffer> obj = Utils::OpenHandle(*input_buffer());
2196     input = Utils::Convert<i::WasmMemoryObject, Value>(
2197         i::WasmMemoryObject::New(i_isolate, obj, kMaxPages));
2198   }
2199   RoundTripTest(input);
2200   ExpectScriptTrue("result instanceof WebAssembly.Memory");
2201   ExpectScriptTrue("result.buffer.byteLength === 65536");
2202   ExpectScriptTrue(
2203       "new Uint8Array(result.buffer, 0, 4).toString() === '0,1,128,255'");
2204 
2205   i::FLAG_experimental_wasm_threads = flag_was_enabled;
2206 }
2207 #endif  // V8_ENABLE_WEBASSEMBLY
2208 
TEST_F(ValueSerializerTest,UnsupportedHostObject)2209 TEST_F(ValueSerializerTest, UnsupportedHostObject) {
2210   InvalidEncodeTest("new ExampleHostObject()");
2211   InvalidEncodeTest("({ a: new ExampleHostObject() })");
2212 }
2213 
2214 class ValueSerializerTestWithHostObject : public ValueSerializerTest {
2215  protected:
ValueSerializerTestWithHostObject()2216   ValueSerializerTestWithHostObject() : serializer_delegate_(this) {}
2217 
2218   static const uint8_t kExampleHostObjectTag;
2219 
WriteExampleHostObjectTag()2220   void WriteExampleHostObjectTag() {
2221     serializer_->WriteRawBytes(&kExampleHostObjectTag, 1);
2222   }
2223 
ReadExampleHostObjectTag()2224   bool ReadExampleHostObjectTag() {
2225     const void* tag;
2226     return deserializer_->ReadRawBytes(1, &tag) &&
2227            *reinterpret_cast<const uint8_t*>(tag) == kExampleHostObjectTag;
2228   }
2229 
2230 // GMock doesn't use the "override" keyword.
2231 #if __clang__
2232 #pragma clang diagnostic push
2233 #pragma clang diagnostic ignored "-Winconsistent-missing-override"
2234 #endif
2235 
2236   class SerializerDelegate : public ValueSerializer::Delegate {
2237    public:
SerializerDelegate(ValueSerializerTestWithHostObject * test)2238     explicit SerializerDelegate(ValueSerializerTestWithHostObject* test)
2239         : test_(test) {}
2240     MOCK_METHOD(Maybe<bool>, WriteHostObject, (Isolate*, Local<Object> object),
2241                 (override));
ThrowDataCloneError(Local<String> message)2242     void ThrowDataCloneError(Local<String> message) override {
2243       test_->isolate()->ThrowException(Exception::Error(message));
2244     }
2245 
2246    private:
2247     ValueSerializerTestWithHostObject* test_;
2248   };
2249 
2250   class DeserializerDelegate : public ValueDeserializer::Delegate {
2251    public:
2252     MOCK_METHOD(MaybeLocal<Object>, ReadHostObject, (Isolate*), (override));
2253   };
2254 
2255 #if __clang__
2256 #pragma clang diagnostic pop
2257 #endif
2258 
GetSerializerDelegate()2259   ValueSerializer::Delegate* GetSerializerDelegate() override {
2260     return &serializer_delegate_;
2261   }
BeforeEncode(ValueSerializer * serializer)2262   void BeforeEncode(ValueSerializer* serializer) override {
2263     serializer_ = serializer;
2264   }
GetDeserializerDelegate()2265   ValueDeserializer::Delegate* GetDeserializerDelegate() override {
2266     return &deserializer_delegate_;
2267   }
BeforeDecode(ValueDeserializer * deserializer)2268   void BeforeDecode(ValueDeserializer* deserializer) override {
2269     deserializer_ = deserializer;
2270   }
2271 
2272   SerializerDelegate serializer_delegate_;
2273   DeserializerDelegate deserializer_delegate_;
2274   ValueSerializer* serializer_;
2275   ValueDeserializer* deserializer_;
2276 
2277   friend class SerializerDelegate;
2278   friend class DeserializerDelegate;
2279 };
2280 
2281 // This is a tag that is used in V8. Using this ensures that we have separate
2282 // tag namespaces.
2283 const uint8_t ValueSerializerTestWithHostObject::kExampleHostObjectTag = 'T';
2284 
TEST_F(ValueSerializerTestWithHostObject,RoundTripUint32)2285 TEST_F(ValueSerializerTestWithHostObject, RoundTripUint32) {
2286   // The host can serialize data as uint32_t.
2287   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2288       .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) {
2289         uint32_t value = 0;
2290         EXPECT_TRUE(object->GetInternalField(0)
2291                         ->Uint32Value(serialization_context())
2292                         .To(&value));
2293         WriteExampleHostObjectTag();
2294         serializer_->WriteUint32(value);
2295         return Just(true);
2296       }));
2297   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2298       .WillRepeatedly(Invoke([this](Isolate*) {
2299         EXPECT_TRUE(ReadExampleHostObjectTag());
2300         uint32_t value = 0;
2301         EXPECT_TRUE(deserializer_->ReadUint32(&value));
2302         Local<Value> argv[] = {Integer::NewFromUnsigned(isolate(), value)};
2303         return NewHostObject(deserialization_context(), arraysize(argv), argv);
2304       }));
2305   Local<Value> value = RoundTripTest("new ExampleHostObject(42)");
2306   ASSERT_TRUE(value->IsObject());
2307   ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount());
2308   ExpectScriptTrue(
2309       "Object.getPrototypeOf(result) === ExampleHostObject.prototype");
2310   ExpectScriptTrue("result.value === 42");
2311 
2312   value = RoundTripTest("new ExampleHostObject(0xCAFECAFE)");
2313   ExpectScriptTrue("result.value === 0xCAFECAFE");
2314 }
2315 
TEST_F(ValueSerializerTestWithHostObject,RoundTripUint64)2316 TEST_F(ValueSerializerTestWithHostObject, RoundTripUint64) {
2317   // The host can serialize data as uint64_t.
2318   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2319       .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) {
2320         uint32_t value = 0, value2 = 0;
2321         EXPECT_TRUE(object->GetInternalField(0)
2322                         ->Uint32Value(serialization_context())
2323                         .To(&value));
2324         EXPECT_TRUE(object->GetInternalField(1)
2325                         ->Uint32Value(serialization_context())
2326                         .To(&value2));
2327         WriteExampleHostObjectTag();
2328         serializer_->WriteUint64((static_cast<uint64_t>(value) << 32) | value2);
2329         return Just(true);
2330       }));
2331   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2332       .WillRepeatedly(Invoke([this](Isolate*) {
2333         EXPECT_TRUE(ReadExampleHostObjectTag());
2334         uint64_t value_packed;
2335         EXPECT_TRUE(deserializer_->ReadUint64(&value_packed));
2336         Local<Value> argv[] = {
2337             Integer::NewFromUnsigned(isolate(),
2338                                      static_cast<uint32_t>(value_packed >> 32)),
2339             Integer::NewFromUnsigned(isolate(),
2340                                      static_cast<uint32_t>(value_packed))};
2341         return NewHostObject(deserialization_context(), arraysize(argv), argv);
2342       }));
2343   Local<Value> value = RoundTripTest("new ExampleHostObject(42, 0)");
2344   ASSERT_TRUE(value->IsObject());
2345   ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount());
2346   ExpectScriptTrue(
2347       "Object.getPrototypeOf(result) === ExampleHostObject.prototype");
2348   ExpectScriptTrue("result.value === 42");
2349   ExpectScriptTrue("result.value2 === 0");
2350 
2351   value = RoundTripTest("new ExampleHostObject(0xFFFFFFFF, 0x12345678)");
2352   ExpectScriptTrue("result.value === 0xFFFFFFFF");
2353   ExpectScriptTrue("result.value2 === 0x12345678");
2354 }
2355 
TEST_F(ValueSerializerTestWithHostObject,RoundTripDouble)2356 TEST_F(ValueSerializerTestWithHostObject, RoundTripDouble) {
2357   // The host can serialize data as double.
2358   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2359       .WillRepeatedly(Invoke([this](Isolate*, Local<Object> object) {
2360         double value = 0;
2361         EXPECT_TRUE(object->GetInternalField(0)
2362                         ->NumberValue(serialization_context())
2363                         .To(&value));
2364         WriteExampleHostObjectTag();
2365         serializer_->WriteDouble(value);
2366         return Just(true);
2367       }));
2368   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2369       .WillRepeatedly(Invoke([this](Isolate*) {
2370         EXPECT_TRUE(ReadExampleHostObjectTag());
2371         double value = 0;
2372         EXPECT_TRUE(deserializer_->ReadDouble(&value));
2373         Local<Value> argv[] = {Number::New(isolate(), value)};
2374         return NewHostObject(deserialization_context(), arraysize(argv), argv);
2375       }));
2376   Local<Value> value = RoundTripTest("new ExampleHostObject(-3.5)");
2377   ASSERT_TRUE(value->IsObject());
2378   ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount());
2379   ExpectScriptTrue(
2380       "Object.getPrototypeOf(result) === ExampleHostObject.prototype");
2381   ExpectScriptTrue("result.value === -3.5");
2382 
2383   value = RoundTripTest("new ExampleHostObject(NaN)");
2384   ExpectScriptTrue("Number.isNaN(result.value)");
2385 
2386   value = RoundTripTest("new ExampleHostObject(Infinity)");
2387   ExpectScriptTrue("result.value === Infinity");
2388 
2389   value = RoundTripTest("new ExampleHostObject(-0)");
2390   ExpectScriptTrue("1/result.value === -Infinity");
2391 }
2392 
TEST_F(ValueSerializerTestWithHostObject,RoundTripRawBytes)2393 TEST_F(ValueSerializerTestWithHostObject, RoundTripRawBytes) {
2394   // The host can serialize arbitrary raw bytes.
2395   const struct {
2396     uint64_t u64;
2397     uint32_t u32;
2398     char str[12];
2399   } sample_data = {0x1234567812345678, 0x87654321, "Hello world"};
2400   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2401       .WillRepeatedly(
2402           Invoke([this, &sample_data](Isolate*, Local<Object> object) {
2403             WriteExampleHostObjectTag();
2404             serializer_->WriteRawBytes(&sample_data, sizeof(sample_data));
2405             return Just(true);
2406           }));
2407   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2408       .WillRepeatedly(Invoke([this, &sample_data](Isolate*) {
2409         EXPECT_TRUE(ReadExampleHostObjectTag());
2410         const void* copied_data = nullptr;
2411         EXPECT_TRUE(
2412             deserializer_->ReadRawBytes(sizeof(sample_data), &copied_data));
2413         if (copied_data) {
2414           EXPECT_EQ(0, memcmp(&sample_data, copied_data, sizeof(sample_data)));
2415         }
2416         return NewHostObject(deserialization_context(), 0, nullptr);
2417       }));
2418   Local<Value> value = RoundTripTest("new ExampleHostObject()");
2419   ASSERT_TRUE(value->IsObject());
2420   ASSERT_TRUE(Object::Cast(*value)->InternalFieldCount());
2421   ExpectScriptTrue(
2422       "Object.getPrototypeOf(result) === ExampleHostObject.prototype");
2423 }
2424 
TEST_F(ValueSerializerTestWithHostObject,RoundTripSameObject)2425 TEST_F(ValueSerializerTestWithHostObject, RoundTripSameObject) {
2426   // If the same object exists in two places, the delegate should be invoked
2427   // only once, and the objects should be the same (by reference equality) on
2428   // the other side.
2429   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2430       .WillOnce(Invoke([this](Isolate*, Local<Object> object) {
2431         WriteExampleHostObjectTag();
2432         return Just(true);
2433       }));
2434   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2435       .WillOnce(Invoke([this](Isolate*) {
2436         EXPECT_TRUE(ReadExampleHostObjectTag());
2437         return NewHostObject(deserialization_context(), 0, nullptr);
2438       }));
2439   RoundTripTest("({ a: new ExampleHostObject(), get b() { return this.a; }})");
2440   ExpectScriptTrue("result.a instanceof ExampleHostObject");
2441   ExpectScriptTrue("result.a === result.b");
2442 }
2443 
TEST_F(ValueSerializerTestWithHostObject,DecodeSimpleHostObject)2444 TEST_F(ValueSerializerTestWithHostObject, DecodeSimpleHostObject) {
2445   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2446       .WillRepeatedly(Invoke([this](Isolate*) {
2447         EXPECT_TRUE(ReadExampleHostObjectTag());
2448         return NewHostObject(deserialization_context(), 0, nullptr);
2449       }));
2450   DecodeTest({0xFF, 0x0D, 0x5C, kExampleHostObjectTag});
2451   ExpectScriptTrue(
2452       "Object.getPrototypeOf(result) === ExampleHostObject.prototype");
2453 }
2454 
2455 class ValueSerializerTestWithHostArrayBufferView
2456     : public ValueSerializerTestWithHostObject {
2457  protected:
BeforeEncode(ValueSerializer * serializer)2458   void BeforeEncode(ValueSerializer* serializer) override {
2459     ValueSerializerTestWithHostObject::BeforeEncode(serializer);
2460     serializer_->SetTreatArrayBufferViewsAsHostObjects(true);
2461   }
2462 };
2463 
TEST_F(ValueSerializerTestWithHostArrayBufferView,RoundTripUint8ArrayInput)2464 TEST_F(ValueSerializerTestWithHostArrayBufferView, RoundTripUint8ArrayInput) {
2465   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2466       .WillOnce(Invoke([this](Isolate*, Local<Object> object) {
2467         EXPECT_TRUE(object->IsUint8Array());
2468         WriteExampleHostObjectTag();
2469         return Just(true);
2470       }));
2471   EXPECT_CALL(deserializer_delegate_, ReadHostObject(isolate()))
2472       .WillOnce(Invoke([this](Isolate*) {
2473         EXPECT_TRUE(ReadExampleHostObjectTag());
2474         return NewDummyUint8Array();
2475       }));
2476   RoundTripTest(
2477       "({ a: new Uint8Array([1, 2, 3]), get b() { return this.a; }})");
2478   ExpectScriptTrue("result.a instanceof Uint8Array");
2479   ExpectScriptTrue("result.a.toString() === '4,5,6'");
2480   ExpectScriptTrue("result.a === result.b");
2481 }
2482 
2483 #if V8_ENABLE_WEBASSEMBLY
2484 // It's expected that WebAssembly has more exhaustive tests elsewhere; this
2485 // mostly checks that the logic to embed it in structured clone serialization
2486 // works correctly.
2487 
2488 // A simple module which exports an "increment" function.
2489 // Copied from test/mjsunit/wasm/incrementer.wasm.
2490 constexpr uint8_t kIncrementerWasm[] = {
2491     0,   97, 115, 109, 1, 0,  0, 0, 1,   6,   1,  96,  1,   127, 1,   127,
2492     3,   2,  1,   0,   7, 13, 1, 9, 105, 110, 99, 114, 101, 109, 101, 110,
2493     116, 0,  0,   10,  9, 1,  7, 0, 32,  0,   65, 1,   106, 11,
2494 };
2495 
2496 class ValueSerializerTestWithWasm : public ValueSerializerTest {
2497  public:
2498   static const char* kUnsupportedSerialization;
2499 
ValueSerializerTestWithWasm()2500   ValueSerializerTestWithWasm()
2501       : serialize_delegate_(&transfer_modules_),
2502         deserialize_delegate_(&transfer_modules_) {}
2503 
Reset()2504   void Reset() {
2505     current_serializer_delegate_ = nullptr;
2506     transfer_modules_.clear();
2507   }
2508 
EnableTransferSerialization()2509   void EnableTransferSerialization() {
2510     current_serializer_delegate_ = &serialize_delegate_;
2511   }
2512 
EnableTransferDeserialization()2513   void EnableTransferDeserialization() {
2514     current_deserializer_delegate_ = &deserialize_delegate_;
2515   }
2516 
EnableThrowingSerializer()2517   void EnableThrowingSerializer() {
2518     current_serializer_delegate_ = &throwing_serializer_;
2519   }
2520 
EnableDefaultDeserializer()2521   void EnableDefaultDeserializer() {
2522     current_deserializer_delegate_ = &default_deserializer_;
2523   }
2524 
2525  protected:
SetUpTestCase()2526   static void SetUpTestCase() {
2527     g_saved_flag = i::FLAG_expose_wasm;
2528     i::FLAG_expose_wasm = true;
2529     ValueSerializerTest::SetUpTestCase();
2530   }
2531 
TearDownTestCase()2532   static void TearDownTestCase() {
2533     ValueSerializerTest::TearDownTestCase();
2534     i::FLAG_expose_wasm = g_saved_flag;
2535     g_saved_flag = false;
2536   }
2537 
2538   class ThrowingSerializer : public ValueSerializer::Delegate {
2539    public:
GetWasmModuleTransferId(Isolate * isolate,Local<WasmModuleObject> module)2540     Maybe<uint32_t> GetWasmModuleTransferId(
2541         Isolate* isolate, Local<WasmModuleObject> module) override {
2542       isolate->ThrowException(Exception::Error(
2543           String::NewFromOneByte(isolate, reinterpret_cast<const uint8_t*>(
2544                                               kUnsupportedSerialization))
2545               .ToLocalChecked()));
2546       return Nothing<uint32_t>();
2547     }
2548 
ThrowDataCloneError(Local<String> message)2549     void ThrowDataCloneError(Local<String> message) override { UNREACHABLE(); }
2550   };
2551 
2552   class SerializeToTransfer : public ValueSerializer::Delegate {
2553    public:
SerializeToTransfer(std::vector<CompiledWasmModule> * modules)2554     explicit SerializeToTransfer(std::vector<CompiledWasmModule>* modules)
2555         : modules_(modules) {}
GetWasmModuleTransferId(Isolate * isolate,Local<WasmModuleObject> module)2556     Maybe<uint32_t> GetWasmModuleTransferId(
2557         Isolate* isolate, Local<WasmModuleObject> module) override {
2558       modules_->push_back(module->GetCompiledModule());
2559       return Just(static_cast<uint32_t>(modules_->size()) - 1);
2560     }
2561 
ThrowDataCloneError(Local<String> message)2562     void ThrowDataCloneError(Local<String> message) override { UNREACHABLE(); }
2563 
2564    private:
2565     std::vector<CompiledWasmModule>* modules_;
2566   };
2567 
2568   class DeserializeFromTransfer : public ValueDeserializer::Delegate {
2569    public:
DeserializeFromTransfer(std::vector<CompiledWasmModule> * modules)2570     explicit DeserializeFromTransfer(std::vector<CompiledWasmModule>* modules)
2571         : modules_(modules) {}
2572 
GetWasmModuleFromId(Isolate * isolate,uint32_t id)2573     MaybeLocal<WasmModuleObject> GetWasmModuleFromId(Isolate* isolate,
2574                                                      uint32_t id) override {
2575       return WasmModuleObject::FromCompiledModule(isolate, modules_->at(id));
2576     }
2577 
2578    private:
2579     std::vector<CompiledWasmModule>* modules_;
2580   };
2581 
GetSerializerDelegate()2582   ValueSerializer::Delegate* GetSerializerDelegate() override {
2583     return current_serializer_delegate_;
2584   }
2585 
GetDeserializerDelegate()2586   ValueDeserializer::Delegate* GetDeserializerDelegate() override {
2587     return current_deserializer_delegate_;
2588   }
2589 
MakeWasm()2590   Local<WasmModuleObject> MakeWasm() {
2591     Context::Scope scope(serialization_context());
2592     i::wasm::ErrorThrower thrower(i_isolate(), "MakeWasm");
2593     auto enabled_features = i::wasm::WasmFeatures::FromIsolate(i_isolate());
2594     i::MaybeHandle<i::JSObject> compiled =
2595         i::wasm::GetWasmEngine()->SyncCompile(
2596             i_isolate(), enabled_features, &thrower,
2597             i::wasm::ModuleWireBytes(base::ArrayVector(kIncrementerWasm)));
2598     CHECK(!thrower.error());
2599     return Local<WasmModuleObject>::Cast(
2600         Utils::ToLocal(compiled.ToHandleChecked()));
2601   }
2602 
ExpectPass()2603   void ExpectPass() {
2604     Local<Value> value = RoundTripTest(MakeWasm());
2605     Context::Scope scope(deserialization_context());
2606     ASSERT_TRUE(value->IsWasmModuleObject());
2607     ExpectScriptTrue(
2608         "new WebAssembly.Instance(result).exports.increment(8) === 9");
2609   }
2610 
ExpectFail()2611   void ExpectFail() {
2612     const std::vector<uint8_t> data = EncodeTest(MakeWasm());
2613     InvalidDecodeTest(data);
2614   }
2615 
GetComplexObjectWithDuplicate()2616   Local<Value> GetComplexObjectWithDuplicate() {
2617     Context::Scope scope(serialization_context());
2618     Local<Value> wasm_module = MakeWasm();
2619     serialization_context()
2620         ->Global()
2621         ->CreateDataProperty(serialization_context(),
2622                              StringFromUtf8("wasm_module"), wasm_module)
2623         .FromMaybe(false);
2624     Local<Script> script =
2625         Script::Compile(
2626             serialization_context(),
2627             StringFromUtf8("({mod1: wasm_module, num: 2, mod2: wasm_module})"))
2628             .ToLocalChecked();
2629     return script->Run(serialization_context()).ToLocalChecked();
2630   }
2631 
VerifyComplexObject(Local<Value> value)2632   void VerifyComplexObject(Local<Value> value) {
2633     ASSERT_TRUE(value->IsObject());
2634     ExpectScriptTrue("result.mod1 instanceof WebAssembly.Module");
2635     ExpectScriptTrue("result.mod2 instanceof WebAssembly.Module");
2636     ExpectScriptTrue("result.num === 2");
2637   }
2638 
GetComplexObjectWithMany()2639   Local<Value> GetComplexObjectWithMany() {
2640     Context::Scope scope(serialization_context());
2641     Local<Value> wasm_module1 = MakeWasm();
2642     Local<Value> wasm_module2 = MakeWasm();
2643     serialization_context()
2644         ->Global()
2645         ->CreateDataProperty(serialization_context(),
2646                              StringFromUtf8("wasm_module1"), wasm_module1)
2647         .FromMaybe(false);
2648     serialization_context()
2649         ->Global()
2650         ->CreateDataProperty(serialization_context(),
2651                              StringFromUtf8("wasm_module2"), wasm_module2)
2652         .FromMaybe(false);
2653     Local<Script> script =
2654         Script::Compile(
2655             serialization_context(),
2656             StringFromUtf8(
2657                 "({mod1: wasm_module1, num: 2, mod2: wasm_module2})"))
2658             .ToLocalChecked();
2659     return script->Run(serialization_context()).ToLocalChecked();
2660   }
2661 
2662  private:
2663   static bool g_saved_flag;
2664   std::vector<CompiledWasmModule> transfer_modules_;
2665   SerializeToTransfer serialize_delegate_;
2666   DeserializeFromTransfer deserialize_delegate_;
2667   ValueSerializer::Delegate* current_serializer_delegate_ = nullptr;
2668   ValueDeserializer::Delegate* current_deserializer_delegate_ = nullptr;
2669   ThrowingSerializer throwing_serializer_;
2670   ValueDeserializer::Delegate default_deserializer_;
2671 };
2672 
2673 bool ValueSerializerTestWithWasm::g_saved_flag = false;
2674 const char* ValueSerializerTestWithWasm::kUnsupportedSerialization =
2675     "Wasm Serialization Not Supported";
2676 
2677 // The default implementation of the serialization
2678 // delegate throws when trying to serialize wasm. The
2679 // embedder must decide serialization policy.
TEST_F(ValueSerializerTestWithWasm,DefaultSerializationDelegate)2680 TEST_F(ValueSerializerTestWithWasm, DefaultSerializationDelegate) {
2681   EnableThrowingSerializer();
2682   Local<Message> message = InvalidEncodeTest(MakeWasm());
2683   size_t msg_len = static_cast<size_t>(message->Get()->Length());
2684   std::unique_ptr<char[]> buff(new char[msg_len + 1]);
2685   message->Get()->WriteOneByte(isolate(),
2686                                reinterpret_cast<uint8_t*>(buff.get()));
2687   // the message ends with the custom error string
2688   size_t custom_msg_len = strlen(kUnsupportedSerialization);
2689   ASSERT_GE(msg_len, custom_msg_len);
2690   size_t start_pos = msg_len - custom_msg_len;
2691   ASSERT_EQ(strcmp(&buff.get()[start_pos], kUnsupportedSerialization), 0);
2692 }
2693 
2694 // The default deserializer throws if wasm transfer is attempted
TEST_F(ValueSerializerTestWithWasm,DefaultDeserializationDelegate)2695 TEST_F(ValueSerializerTestWithWasm, DefaultDeserializationDelegate) {
2696   EnableTransferSerialization();
2697   EnableDefaultDeserializer();
2698   ExpectFail();
2699 }
2700 
2701 // We only want to allow deserialization through
2702 // transferred modules - which requres both serializer
2703 // and deserializer to understand that - or through
2704 // explicitly allowing inlined data, which requires
2705 // deserializer opt-in (we default the serializer to
2706 // inlined data because we don't trust that data on the
2707 // receiving end anyway).
2708 
TEST_F(ValueSerializerTestWithWasm,RoundtripWasmTransfer)2709 TEST_F(ValueSerializerTestWithWasm, RoundtripWasmTransfer) {
2710   EnableTransferSerialization();
2711   EnableTransferDeserialization();
2712   ExpectPass();
2713 }
2714 
TEST_F(ValueSerializerTestWithWasm,CannotTransferWasmWhenExpectingInline)2715 TEST_F(ValueSerializerTestWithWasm, CannotTransferWasmWhenExpectingInline) {
2716   EnableTransferSerialization();
2717   ExpectFail();
2718 }
2719 
TEST_F(ValueSerializerTestWithWasm,ComplexObjectDuplicateTransfer)2720 TEST_F(ValueSerializerTestWithWasm, ComplexObjectDuplicateTransfer) {
2721   EnableTransferSerialization();
2722   EnableTransferDeserialization();
2723   Local<Value> value = RoundTripTest(GetComplexObjectWithDuplicate());
2724   VerifyComplexObject(value);
2725   ExpectScriptTrue("result.mod1 === result.mod2");
2726 }
2727 
TEST_F(ValueSerializerTestWithWasm,ComplexObjectWithManyTransfer)2728 TEST_F(ValueSerializerTestWithWasm, ComplexObjectWithManyTransfer) {
2729   EnableTransferSerialization();
2730   EnableTransferDeserialization();
2731   Local<Value> value = RoundTripTest(GetComplexObjectWithMany());
2732   VerifyComplexObject(value);
2733   ExpectScriptTrue("result.mod1 != result.mod2");
2734 }
2735 #endif  // V8_ENABLE_WEBASSEMBLY
2736 
2737 class ValueSerializerTestWithLimitedMemory : public ValueSerializerTest {
2738  protected:
2739 // GMock doesn't use the "override" keyword.
2740 #if __clang__
2741 #pragma clang diagnostic push
2742 #pragma clang diagnostic ignored "-Winconsistent-missing-override"
2743 #endif
2744 
2745   class SerializerDelegate : public ValueSerializer::Delegate {
2746    public:
SerializerDelegate(ValueSerializerTestWithLimitedMemory * test)2747     explicit SerializerDelegate(ValueSerializerTestWithLimitedMemory* test)
2748         : test_(test) {}
2749 
~SerializerDelegate()2750     ~SerializerDelegate() { EXPECT_EQ(nullptr, last_buffer_); }
2751 
SetMemoryLimit(size_t limit)2752     void SetMemoryLimit(size_t limit) { memory_limit_ = limit; }
2753 
ReallocateBufferMemory(void * old_buffer,size_t size,size_t * actual_size)2754     void* ReallocateBufferMemory(void* old_buffer, size_t size,
2755                                  size_t* actual_size) override {
2756       EXPECT_EQ(old_buffer, last_buffer_);
2757       if (size > memory_limit_) return nullptr;
2758       *actual_size = size;
2759       last_buffer_ = realloc(old_buffer, size);
2760       return last_buffer_;
2761     }
2762 
FreeBufferMemory(void * buffer)2763     void FreeBufferMemory(void* buffer) override {
2764       EXPECT_EQ(buffer, last_buffer_);
2765       last_buffer_ = nullptr;
2766       free(buffer);
2767     }
2768 
ThrowDataCloneError(Local<String> message)2769     void ThrowDataCloneError(Local<String> message) override {
2770       test_->isolate()->ThrowException(Exception::Error(message));
2771     }
2772 
2773     MOCK_METHOD(Maybe<bool>, WriteHostObject, (Isolate*, Local<Object> object),
2774                 (override));
2775 
2776    private:
2777     ValueSerializerTestWithLimitedMemory* test_;
2778     void* last_buffer_ = nullptr;
2779     size_t memory_limit_ = 0;
2780   };
2781 
2782 #if __clang__
2783 #pragma clang diagnostic pop
2784 #endif
2785 
GetSerializerDelegate()2786   ValueSerializer::Delegate* GetSerializerDelegate() override {
2787     return &serializer_delegate_;
2788   }
2789 
BeforeEncode(ValueSerializer * serializer)2790   void BeforeEncode(ValueSerializer* serializer) override {
2791     serializer_ = serializer;
2792   }
2793 
2794   SerializerDelegate serializer_delegate_{this};
2795   ValueSerializer* serializer_ = nullptr;
2796 };
2797 
TEST_F(ValueSerializerTestWithLimitedMemory,FailIfNoMemoryInWriteHostObject)2798 TEST_F(ValueSerializerTestWithLimitedMemory, FailIfNoMemoryInWriteHostObject) {
2799   EXPECT_CALL(serializer_delegate_, WriteHostObject(isolate(), _))
2800       .WillRepeatedly(Invoke([this](Isolate*, Local<Object>) {
2801         static const char kDummyData[1024] = {};
2802         serializer_->WriteRawBytes(&kDummyData, sizeof(kDummyData));
2803         return Just(true);
2804       }));
2805 
2806   // If there is enough memory, things work.
2807   serializer_delegate_.SetMemoryLimit(2048);
2808   EncodeTest("new ExampleHostObject()");
2809 
2810   // If not, we get a graceful failure, rather than silent misbehavior.
2811   serializer_delegate_.SetMemoryLimit(1024);
2812   InvalidEncodeTest("new ExampleHostObject()");
2813 
2814   // And we definitely don't continue to serialize other things.
2815   serializer_delegate_.SetMemoryLimit(1024);
2816   EvaluateScriptForInput("gotA = false");
2817   InvalidEncodeTest("[new ExampleHostObject, {get a() { gotA = true; }}]");
2818   EXPECT_TRUE(EvaluateScriptForInput("gotA")->IsFalse());
2819 }
2820 
2821 // We only have basic tests and tests for .stack here, because we have more
2822 // comprehensive tests as web platform tests.
TEST_F(ValueSerializerTest,RoundTripError)2823 TEST_F(ValueSerializerTest, RoundTripError) {
2824   Local<Value> value = RoundTripTest("Error('hello')");
2825   ASSERT_TRUE(value->IsObject());
2826   Local<Object> error = value.As<Object>();
2827 
2828   Local<Value> name;
2829   Local<Value> message;
2830 
2831   {
2832     Context::Scope scope(deserialization_context());
2833     EXPECT_EQ(error->GetPrototype(), Exception::Error(String::Empty(isolate()))
2834                                          .As<Object>()
2835                                          ->GetPrototype());
2836   }
2837   ASSERT_TRUE(error->Get(deserialization_context(), StringFromUtf8("name"))
2838                   .ToLocal(&name));
2839   ASSERT_TRUE(name->IsString());
2840   EXPECT_EQ(Utf8Value(name), "Error");
2841 
2842   ASSERT_TRUE(error->Get(deserialization_context(), StringFromUtf8("message"))
2843                   .ToLocal(&message));
2844   ASSERT_TRUE(message->IsString());
2845   EXPECT_EQ(Utf8Value(message), "hello");
2846 }
2847 
TEST_F(ValueSerializerTest,DefaultErrorStack)2848 TEST_F(ValueSerializerTest, DefaultErrorStack) {
2849   Local<Value> value =
2850       RoundTripTest("function hkalkcow() { return Error(); } hkalkcow();");
2851   ASSERT_TRUE(value->IsObject());
2852   Local<Object> error = value.As<Object>();
2853 
2854   Local<Value> stack;
2855   ASSERT_TRUE(error->Get(deserialization_context(), StringFromUtf8("stack"))
2856                   .ToLocal(&stack));
2857   ASSERT_TRUE(stack->IsString());
2858   EXPECT_NE(Utf8Value(stack).find("hkalkcow"), std::string::npos);
2859 }
2860 
TEST_F(ValueSerializerTest,ModifiedErrorStack)2861 TEST_F(ValueSerializerTest, ModifiedErrorStack) {
2862   Local<Value> value = RoundTripTest("let e = Error(); e.stack = 'hello'; e");
2863   ASSERT_TRUE(value->IsObject());
2864   Local<Object> error = value.As<Object>();
2865 
2866   Local<Value> stack;
2867   ASSERT_TRUE(error->Get(deserialization_context(), StringFromUtf8("stack"))
2868                   .ToLocal(&stack));
2869   ASSERT_TRUE(stack->IsString());
2870   EXPECT_EQ(Utf8Value(stack), "hello");
2871 }
2872 
TEST_F(ValueSerializerTest,NonStringErrorStack)2873 TEST_F(ValueSerializerTest, NonStringErrorStack) {
2874   Local<Value> value = RoundTripTest("let e = Error(); e.stack = 17; e");
2875   ASSERT_TRUE(value->IsObject());
2876   Local<Object> error = value.As<Object>();
2877 
2878   Local<Value> stack;
2879   ASSERT_TRUE(error->Get(deserialization_context(), StringFromUtf8("stack"))
2880                   .ToLocal(&stack));
2881   EXPECT_TRUE(stack->IsUndefined());
2882 }
2883 
2884 }  // namespace
2885 }  // namespace v8
2886