summaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/value-serializer-unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/value-serializer-unittest.cc')
-rw-r--r--deps/v8/test/unittests/value-serializer-unittest.cc296
1 files changed, 235 insertions, 61 deletions
diff --git a/deps/v8/test/unittests/value-serializer-unittest.cc b/deps/v8/test/unittests/value-serializer-unittest.cc
index d88d60a3e6..1dabd2a17a 100644
--- a/deps/v8/test/unittests/value-serializer-unittest.cc
+++ b/deps/v8/test/unittests/value-serializer-unittest.cc
@@ -64,6 +64,7 @@ class ValueSerializerTest : public TestWithIsolate {
// Overridden in more specific fixtures.
virtual ValueSerializer::Delegate* GetSerializerDelegate() { return nullptr; }
virtual void BeforeEncode(ValueSerializer*) {}
+ virtual void AfterEncode() {}
virtual ValueDeserializer::Delegate* GetDeserializerDelegate() {
return nullptr;
}
@@ -109,7 +110,11 @@ class ValueSerializerTest : public TestWithIsolate {
if (!serializer.WriteValue(context, value).FromMaybe(false)) {
return Nothing<std::vector<uint8_t>>();
}
- return Just(serializer.ReleaseBuffer());
+ AfterEncode();
+ std::pair<uint8_t*, size_t> buffer = serializer.Release();
+ std::vector<uint8_t> result(buffer.first, buffer.first + buffer.second);
+ free(buffer.first);
+ return Just(std::move(result));
}
template <typename InputFunctor, typename EncodedDataFunctor>
@@ -173,7 +178,7 @@ class ValueSerializerTest : public TestWithIsolate {
deserializer.SetSupportsLegacyWireFormat(true);
BeforeDecode(&deserializer);
ASSERT_TRUE(deserializer.ReadHeader(context).FromMaybe(false));
- ASSERT_EQ(0, deserializer.GetWireFormatVersion());
+ ASSERT_EQ(0u, deserializer.GetWireFormatVersion());
Local<Value> result;
ASSERT_TRUE(deserializer.ReadValue(context).ToLocal(&result));
ASSERT_FALSE(result.IsEmpty());
@@ -800,7 +805,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
// A simple array of integers.
RoundTripTest("[1, 2, 3, 4, 5]", [this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- EXPECT_EQ(5, Array::Cast(*value)->Length());
+ EXPECT_EQ(5u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Array.prototype"));
EXPECT_TRUE(
@@ -811,14 +816,14 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
"(() => { var x = new Array(1000); x[500] = 42; return x; })()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- EXPECT_EQ(1000, Array::Cast(*value)->Length());
+ EXPECT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[500] === 42"));
});
// Duplicate reference.
RoundTripTest(
"(() => { var y = {}; return [y, y]; })()", [this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result[1]"));
});
// Duplicate reference in a sparse array.
@@ -826,7 +831,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
"(() => { var x = new Array(1000); x[1] = x[500] = {}; return x; })()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("typeof result[1] === 'object'"));
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === result[500]"));
@@ -836,7 +841,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
"(() => { var y = []; y[0] = y; return y; })()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1, Array::Cast(*value)->Length());
+ ASSERT_EQ(1u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result"));
});
// Self reference in a sparse array.
@@ -844,7 +849,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
"(() => { var y = new Array(1000); y[519] = y; return y; })()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[519] === result"));
});
// Array with additional properties.
@@ -852,7 +857,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
"(() => { var y = [1, 2]; y.foo = 'bar'; return y; })()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result.toString() === '1,2'"));
EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'"));
});
@@ -861,7 +866,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
"(() => { var y = new Array(1000); y.foo = 'bar'; return y; })()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"result.toString() === ','.repeat(999)"));
EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'"));
@@ -869,7 +874,7 @@ TEST_F(ValueSerializerTest, RoundTripArray) {
// The distinction between holes and undefined elements must be maintained.
RoundTripTest("[,undefined]", [this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("typeof result[0] === 'undefined'"));
EXPECT_TRUE(
@@ -886,7 +891,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x49, 0x08, 0x3f, 0x01, 0x49, 0x0a, 0x24, 0x00, 0x05, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- EXPECT_EQ(5, Array::Cast(*value)->Length());
+ EXPECT_EQ(5u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Array.prototype"));
EXPECT_TRUE(EvaluateScriptForResultBool(
@@ -897,7 +902,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0xe8, 0x07, 0x3f, 0x01, 0x49, 0x54, 0x40, 0x01, 0xe8, 0x07},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- EXPECT_EQ(1000, Array::Cast(*value)->Length());
+ EXPECT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[500] === 42"));
});
// Duplicate reference.
@@ -906,7 +911,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x02, 0x5e, 0x01, 0x24, 0x00, 0x02},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result[1]"));
});
// Duplicate reference in a sparse array.
@@ -916,7 +921,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x07, 0x3f, 0x02, 0x5e, 0x01, 0x40, 0x02, 0xe8, 0x07, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("typeof result[1] === 'object'"));
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === result[500]"));
@@ -926,7 +931,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x00, 0x01, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1, Array::Cast(*value)->Length());
+ ASSERT_EQ(1u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === result"));
});
// Self reference in a sparse array.
@@ -935,7 +940,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x8e, 0x08, 0x3f, 0x01, 0x5e, 0x00, 0x40, 0x01, 0xe8, 0x07},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[519] === result"));
});
// Array with additional properties.
@@ -945,7 +950,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x01, 0x53, 0x03, 0x62, 0x61, 0x72, 0x24, 0x01, 0x02, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result.toString() === '1,2'"));
EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'"));
});
@@ -955,7 +960,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
0x62, 0x61, 0x72, 0x40, 0x01, 0xe8, 0x07, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"result.toString() === ','.repeat(999)"));
EXPECT_TRUE(EvaluateScriptForResultBool("result.foo === 'bar'"));
@@ -967,7 +972,7 @@ TEST_F(ValueSerializerTest, DecodeArray) {
{0xff, 0x09, 0x61, 0x02, 0x49, 0x02, 0x5f, 0x40, 0x01, 0x02},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("typeof result[0] === 'undefined'"));
EXPECT_TRUE(
@@ -977,6 +982,14 @@ TEST_F(ValueSerializerTest, DecodeArray) {
});
}
+TEST_F(ValueSerializerTest, DecodeInvalidOverLargeArray) {
+ // So large it couldn't exist in the V8 heap, and its size couldn't fit in a
+ // SMI on 32-bit systems (2^30).
+ InvalidDecodeTest({0xff, 0x09, 0x41, 0x80, 0x80, 0x80, 0x80, 0x04});
+ // Not so large, but there isn't enough data left in the buffer.
+ InvalidDecodeTest({0xff, 0x09, 0x41, 0x01});
+}
+
TEST_F(ValueSerializerTest, RoundTripArrayWithNonEnumerableElement) {
// Even though this array looks like [1,5,3], the 5 should be missing from the
// perspective of structured clone, which only clones properties that were
@@ -989,7 +1002,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithNonEnumerableElement) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(3, Array::Cast(*value)->Length());
+ ASSERT_EQ(3u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty('1')"));
});
}
@@ -1003,7 +1016,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("typeof result[1] === 'undefined'"));
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(1)"));
@@ -1017,7 +1030,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("typeof result[1] === 'undefined'"));
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(1)"));
@@ -1031,7 +1044,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(4, Array::Cast(*value)->Length());
+ ASSERT_EQ(4u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === 1"));
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(2)"));
});
@@ -1044,7 +1057,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(4, Array::Cast(*value)->Length());
+ ASSERT_EQ(4u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[2] === 3"));
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(3)"));
});
@@ -1057,7 +1070,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[0] === 1"));
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(2)"));
});
@@ -1069,7 +1082,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[2] === 3"));
EXPECT_TRUE(EvaluateScriptForResultBool("!result.hasOwnProperty(3)"));
});
@@ -1084,7 +1097,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 3"));
});
// Same for sparse arrays.
@@ -1098,7 +1111,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 3"));
});
// Getters on the array itself must also run.
@@ -1110,7 +1123,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(3, Array::Cast(*value)->Length());
+ ASSERT_EQ(3u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 4"));
});
// Same for sparse arrays.
@@ -1123,7 +1136,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] === 4"));
});
// Even with a getter that deletes things, we don't read from the prototype.
@@ -1135,7 +1148,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(2, Array::Cast(*value)->Length());
+ ASSERT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)"));
});
// Same for sparse arrays.
@@ -1148,7 +1161,7 @@ TEST_F(ValueSerializerTest, RoundTripArrayWithTrickyGetters) {
"})()",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(1000, Array::Cast(*value)->Length());
+ ASSERT_EQ(1000u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)"));
});
}
@@ -1158,7 +1171,7 @@ TEST_F(ValueSerializerTest, DecodeSparseArrayVersion0) {
DecodeTestForVersion0({0x40, 0x00, 0x00, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- ASSERT_EQ(0, Array::Cast(*value)->Length());
+ ASSERT_EQ(0u, Array::Cast(*value)->Length());
});
// Sparse array with a mixture of elements and properties.
DecodeTestForVersion0(
@@ -1167,7 +1180,7 @@ TEST_F(ValueSerializerTest, DecodeSparseArrayVersion0) {
0x03, 'b', 'a', 'z', 0x49, 0x0b, 0x40, 0x04, 0x03, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- EXPECT_EQ(3, Array::Cast(*value)->Length());
+ EXPECT_EQ(3u, Array::Cast(*value)->Length());
EXPECT_TRUE(
EvaluateScriptForResultBool("result.toString() === 'a,,5'"));
EXPECT_TRUE(EvaluateScriptForResultBool("!(1 in result)"));
@@ -1179,7 +1192,7 @@ TEST_F(ValueSerializerTest, DecodeSparseArrayVersion0) {
{0x55, 0x01, 0x55, 0x01, 0x54, 0x40, 0x01, 0x02, 0x40, 0x01, 0x02, 0x00},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsArray());
- EXPECT_EQ(2, Array::Cast(*value)->Length());
+ EXPECT_EQ(2u, Array::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool("!(0 in result)"));
EXPECT_TRUE(EvaluateScriptForResultBool("result[1] instanceof Array"));
EXPECT_TRUE(EvaluateScriptForResultBool("!(0 in result[1])"));
@@ -1732,7 +1745,6 @@ class ValueSerializerTestWithArrayBufferTransfer : public ValueSerializerTest {
{
Context::Scope scope(serialization_context());
input_buffer_ = ArrayBuffer::New(isolate(), nullptr, 0);
- input_buffer_->Neuter();
}
{
Context::Scope scope(deserialization_context());
@@ -1749,6 +1761,8 @@ class ValueSerializerTestWithArrayBufferTransfer : public ValueSerializerTest {
serializer->TransferArrayBuffer(0, input_buffer_);
}
+ void AfterEncode() override { input_buffer_->Neuter(); }
+
void BeforeDecode(ValueDeserializer* deserializer) override {
deserializer->TransferArrayBuffer(0, output_buffer_);
}
@@ -1797,8 +1811,8 @@ TEST_F(ValueSerializerTest, RoundTripTypedArray) {
#define TYPED_ARRAY_ROUND_TRIP_TEST(Type, type, TYPE, ctype, size) \
RoundTripTest("new " #Type "Array(2)", [this](Local<Value> value) { \
ASSERT_TRUE(value->Is##Type##Array()); \
- EXPECT_EQ(2 * size, TypedArray::Cast(*value)->ByteLength()); \
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length()); \
+ EXPECT_EQ(2u * size, TypedArray::Cast(*value)->ByteLength()); \
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length()); \
EXPECT_TRUE(EvaluateScriptForResultBool( \
"Object.getPrototypeOf(result) === " #Type "Array.prototype")); \
});
@@ -1852,8 +1866,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x42, 0x00, 0x02},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsUint8Array());
- EXPECT_EQ(2, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Uint8Array.prototype"));
});
@@ -1861,8 +1875,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x62, 0x00, 0x02},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsInt8Array());
- EXPECT_EQ(2, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Int8Array.prototype"));
});
@@ -1871,8 +1885,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x00, 0x56, 0x57, 0x00, 0x04},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsUint16Array());
- EXPECT_EQ(4, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(4u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Uint16Array.prototype"));
});
@@ -1880,8 +1894,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x00, 0x56, 0x77, 0x00, 0x04},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsInt16Array());
- EXPECT_EQ(4, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(4u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Int16Array.prototype"));
});
@@ -1889,8 +1903,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x44, 0x00, 0x08},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsUint32Array());
- EXPECT_EQ(8, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Uint32Array.prototype"));
});
@@ -1898,8 +1912,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x64, 0x00, 0x08},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsInt32Array());
- EXPECT_EQ(8, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Int32Array.prototype"));
});
@@ -1907,8 +1921,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x66, 0x00, 0x08},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsFloat32Array());
- EXPECT_EQ(8, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(8u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Float32Array.prototype"));
});
@@ -1917,8 +1931,8 @@ TEST_F(ValueSerializerTest, DecodeTypedArray) {
0x00, 0x00, 0x00, 0x00, 0x56, 0x46, 0x00, 0x10},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsFloat64Array());
- EXPECT_EQ(16, TypedArray::Cast(*value)->ByteLength());
- EXPECT_EQ(2, TypedArray::Cast(*value)->Length());
+ EXPECT_EQ(16u, TypedArray::Cast(*value)->ByteLength());
+ EXPECT_EQ(2u, TypedArray::Cast(*value)->Length());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === Float64Array.prototype"));
});
@@ -1984,15 +1998,18 @@ TEST_F(ValueSerializerTest, DecodeInvalidTypedArray) {
// Byte length not divisible by element size.
InvalidDecodeTest(
{0xff, 0x09, 0x42, 0x04, 0x00, 0x00, 0x00, 0x00, 0x56, 0x77, 0x02, 0x01});
+ // Invalid view type (0xff).
+ InvalidDecodeTest(
+ {0xff, 0x09, 0x42, 0x02, 0x00, 0x00, 0x56, 0xff, 0x01, 0x01});
}
TEST_F(ValueSerializerTest, RoundTripDataView) {
RoundTripTest("new DataView(new ArrayBuffer(4), 1, 2)",
[this](Local<Value> value) {
ASSERT_TRUE(value->IsDataView());
- EXPECT_EQ(1, DataView::Cast(*value)->ByteOffset());
- EXPECT_EQ(2, DataView::Cast(*value)->ByteLength());
- EXPECT_EQ(4, DataView::Cast(*value)->Buffer()->ByteLength());
+ EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset());
+ EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength());
+ EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === DataView.prototype"));
});
@@ -2003,9 +2020,9 @@ TEST_F(ValueSerializerTest, DecodeDataView) {
0x00, 0x56, 0x3f, 0x01, 0x02},
[this](Local<Value> value) {
ASSERT_TRUE(value->IsDataView());
- EXPECT_EQ(1, DataView::Cast(*value)->ByteOffset());
- EXPECT_EQ(2, DataView::Cast(*value)->ByteLength());
- EXPECT_EQ(4, DataView::Cast(*value)->Buffer()->ByteLength());
+ EXPECT_EQ(1u, DataView::Cast(*value)->ByteOffset());
+ EXPECT_EQ(2u, DataView::Cast(*value)->ByteLength());
+ EXPECT_EQ(4u, DataView::Cast(*value)->Buffer()->ByteLength());
EXPECT_TRUE(EvaluateScriptForResultBool(
"Object.getPrototypeOf(result) === DataView.prototype"));
});
@@ -2358,5 +2375,162 @@ TEST_F(ValueSerializerTestWithHostObject, RoundTripSameObject) {
});
}
+// It's expected that WebAssembly has more exhaustive tests elsewhere; this
+// mostly checks that the logic to embed it in structured clone serialization
+// works correctly.
+
+class ValueSerializerTestWithWasm : public ValueSerializerTest {
+ protected:
+ static void SetUpTestCase() {
+ g_saved_flag = i::FLAG_expose_wasm;
+ i::FLAG_expose_wasm = true;
+ ValueSerializerTest::SetUpTestCase();
+ }
+
+ static void TearDownTestCase() {
+ ValueSerializerTest::TearDownTestCase();
+ i::FLAG_expose_wasm = g_saved_flag;
+ g_saved_flag = false;
+ }
+
+ private:
+ static bool g_saved_flag;
+};
+
+bool ValueSerializerTestWithWasm::g_saved_flag = false;
+
+// A simple module which exports an "increment" function.
+// Copied from test/mjsunit/wasm/incrementer.wasm.
+const unsigned char kIncrementerWasm[] = {
+ 0x00, 0x61, 0x73, 0x6d, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60,
+ 0x01, 0x7f, 0x01, 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x0d, 0x01, 0x09,
+ 0x69, 0x6e, 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x0a,
+ 0x08, 0x01, 0x06, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a};
+
+TEST_F(ValueSerializerTestWithWasm, RoundTripWasmModule) {
+ RoundTripTest(
+ [this]() {
+ return WasmCompiledModule::DeserializeOrCompile(
+ isolate(), {nullptr, 0},
+ {kIncrementerWasm, sizeof(kIncrementerWasm)})
+ .ToLocalChecked();
+ },
+ [this](Local<Value> value) {
+ ASSERT_TRUE(value->IsWebAssemblyCompiledModule());
+ EXPECT_TRUE(EvaluateScriptForResultBool(
+ "new WebAssembly.Instance(result).exports.increment(8) === 9"));
+ });
+}
+
+// As produced around Chrome 56.
+const unsigned char kSerializedIncrementerWasm[] = {
+ 0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x2d, 0x00, 0x61, 0x73, 0x6d, 0x0d,
+ 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7f, 0x01, 0x7f, 0x03,
+ 0x02, 0x01, 0x00, 0x07, 0x0d, 0x01, 0x09, 0x69, 0x6e, 0x63, 0x72, 0x65,
+ 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x0a, 0x08, 0x01, 0x06, 0x00, 0x20,
+ 0x00, 0x41, 0x01, 0x6a, 0xf8, 0x04, 0xa1, 0x06, 0xde, 0xc0, 0xc6, 0x44,
+ 0x3c, 0x29, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x02, 0x00, 0x00, 0x81, 0x4e,
+ 0xce, 0x7c, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x30, 0x02,
+ 0x00, 0x00, 0xb0, 0x25, 0x30, 0xe3, 0xf2, 0xdb, 0x2e, 0x48, 0x00, 0x00,
+ 0x00, 0x80, 0xe8, 0x00, 0x00, 0x80, 0xe0, 0x01, 0x00, 0x80, 0x00, 0x00,
+ 0x00, 0x80, 0x00, 0x00, 0x00, 0x80, 0x07, 0x08, 0x00, 0x00, 0x09, 0x04,
+ 0x10, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x3c, 0x8c, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x01, 0x10, 0x8c, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x70, 0x94, 0x01, 0x0c, 0x8b,
+ 0xc1, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x25, 0xdc, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x9e, 0x01, 0x10, 0x8c, 0xc0, 0x00, 0x00,
+ 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x84, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x05, 0x7d, 0x01, 0x1a, 0xe1, 0x02, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x23, 0x88, 0x42, 0x32, 0x03,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x04, 0x00,
+ 0x00, 0x02, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x49, 0x3b, 0xa5, 0x60, 0x0c, 0x00,
+ 0x00, 0x0f, 0x86, 0x04, 0x00, 0x00, 0x00, 0x83, 0xc0, 0x01, 0xc3, 0x55,
+ 0x48, 0x89, 0xe5, 0x49, 0xba, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
+ 0x00, 0x41, 0x52, 0x48, 0x83, 0xec, 0x08, 0x48, 0x89, 0x45, 0xf0, 0x48,
+ 0xbb, 0xb0, 0x67, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0xc0, 0x48,
+ 0xbe, 0xe1, 0x57, 0x81, 0x85, 0xf6, 0x14, 0x00, 0x00, 0xe8, 0xfc, 0x3c,
+ 0xea, 0xff, 0x48, 0x8b, 0x45, 0xf0, 0x48, 0x8b, 0xe5, 0x5d, 0xeb, 0xbf,
+ 0x66, 0x90, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x44, 0x00,
+ 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x0f, 0x20, 0x84, 0x0f, 0x7d, 0x01, 0x0d, 0x00, 0x0f, 0x04,
+ 0x6d, 0x08, 0x0f, 0xf0, 0x02, 0x80, 0x94, 0x01, 0x0c, 0x8b, 0xc1, 0x00,
+ 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0xed, 0xa9, 0x2d, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x9e, 0xe0, 0x38, 0x1a, 0x61, 0x03, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x23, 0x88, 0x42, 0x32, 0x03, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9a, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x4e, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00,
+ 0x02, 0xf9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0xff, 0x00, 0x00, 0x00, 0x00, 0x55, 0x48, 0x89, 0xe5, 0x56, 0x57, 0x48,
+ 0x8b, 0x45, 0x10, 0xe8, 0x11, 0xed, 0xed, 0xff, 0xa8, 0x01, 0x0f, 0x85,
+ 0x2d, 0x00, 0x00, 0x00, 0x48, 0xc1, 0xe8, 0x20, 0xc5, 0xf9, 0x57, 0xc0,
+ 0xc5, 0xfb, 0x2a, 0xc0, 0xc4, 0xe1, 0xfb, 0x2c, 0xc0, 0x48, 0x83, 0xf8,
+ 0x01, 0x0f, 0x80, 0x34, 0x00, 0x00, 0x00, 0x8b, 0xc0, 0xe8, 0x27, 0xfe,
+ 0xff, 0xff, 0x48, 0xc1, 0xe0, 0x20, 0x48, 0x8b, 0xe5, 0x5d, 0xc2, 0x10,
+ 0x00, 0x49, 0x39, 0x45, 0xa0, 0x0f, 0x84, 0x07, 0x00, 0x00, 0x00, 0xc5,
+ 0xfb, 0x10, 0x40, 0x07, 0xeb, 0xce, 0x49, 0xba, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0xf8, 0x7f, 0xc4, 0xc1, 0xf9, 0x6e, 0xc2, 0xeb, 0xbd, 0x48,
+ 0x83, 0xec, 0x08, 0xc5, 0xfb, 0x11, 0x04, 0x24, 0xe8, 0xcc, 0xfe, 0xff,
+ 0xff, 0x48, 0x83, 0xc4, 0x08, 0xeb, 0xb8, 0x66, 0x90, 0x02, 0x00, 0x00,
+ 0x00, 0x03, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
+ 0x0f, 0x39, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x0f, 0xff, 0xff, 0x00,
+ 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x20, 0x84,
+ 0x0f, 0xcc, 0x6e, 0x7d, 0x01, 0x72, 0x98, 0x00, 0x0f, 0xdc, 0x6d, 0x0c,
+ 0x0f, 0xb0, 0x84, 0x0d, 0x04, 0x84, 0xe3, 0xc0, 0x00, 0x00, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x84, 0xe0, 0x84, 0x84, 0x18, 0x2f, 0x2f, 0x2f,
+ 0x2f, 0x2f};
+
+TEST_F(ValueSerializerTestWithWasm, DecodeWasmModule) {
+ std::vector<uint8_t> raw(
+ kSerializedIncrementerWasm,
+ kSerializedIncrementerWasm + sizeof(kSerializedIncrementerWasm));
+ DecodeTest(raw, [this](Local<Value> value) {
+ ASSERT_TRUE(value->IsWebAssemblyCompiledModule());
+ EXPECT_TRUE(EvaluateScriptForResultBool(
+ "new WebAssembly.Instance(result).exports.increment(8) === 9"));
+ });
+}
+
+// As above, but with empty compiled data. Should work due to fallback to wire
+// data.
+const unsigned char kSerializedIncrementerWasmWithInvalidCompiledData[] = {
+ 0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x2d, 0x00, 0x61, 0x73, 0x6d,
+ 0x0d, 0x00, 0x00, 0x00, 0x01, 0x06, 0x01, 0x60, 0x01, 0x7f, 0x01,
+ 0x7f, 0x03, 0x02, 0x01, 0x00, 0x07, 0x0d, 0x01, 0x09, 0x69, 0x6e,
+ 0x63, 0x72, 0x65, 0x6d, 0x65, 0x6e, 0x74, 0x00, 0x00, 0x0a, 0x08,
+ 0x01, 0x06, 0x00, 0x20, 0x00, 0x41, 0x01, 0x6a, 0x00};
+
+TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidCompiledData) {
+ std::vector<uint8_t> raw(
+ kSerializedIncrementerWasmWithInvalidCompiledData,
+ kSerializedIncrementerWasmWithInvalidCompiledData +
+ sizeof(kSerializedIncrementerWasmWithInvalidCompiledData));
+ DecodeTest(raw, [this](Local<Value> value) {
+ ASSERT_TRUE(value->IsWebAssemblyCompiledModule());
+ EXPECT_TRUE(EvaluateScriptForResultBool(
+ "new WebAssembly.Instance(result).exports.increment(8) === 9"));
+ });
+}
+
+// As above, but also with empty wire data. Should fail.
+const unsigned char kSerializedIncrementerWasmInvalid[] = {
+ 0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x00};
+
+TEST_F(ValueSerializerTestWithWasm,
+ DecodeWasmModuleWithInvalidCompiledAndWireData) {
+ std::vector<uint8_t> raw(kSerializedIncrementerWasmInvalid,
+ kSerializedIncrementerWasmInvalid +
+ sizeof(kSerializedIncrementerWasmInvalid));
+ InvalidDecodeTest(raw);
+}
+
+TEST_F(ValueSerializerTestWithWasm, DecodeWasmModuleWithInvalidDataLength) {
+ InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x7f, 0x00});
+ InvalidDecodeTest({0xff, 0x09, 0x3f, 0x00, 0x57, 0x79, 0x00, 0x7f});
+}
+
} // namespace
} // namespace v8