Index: test/unittests/value-serializer-unittest.cc |
diff --git a/test/unittests/value-serializer-unittest.cc b/test/unittests/value-serializer-unittest.cc |
index c0037efb01709e9c401992d89292422494bf18c1..fdde727a27ca1542cd05471dfca8d0ece033af51 100644 |
--- a/test/unittests/value-serializer-unittest.cc |
+++ b/test/unittests/value-serializer-unittest.cc |
@@ -2595,6 +2595,26 @@ TEST_F(ValueSerializerTestWithHostArrayBufferView, RoundTripUint8ArrayInput) { |
// works correctly. |
class ValueSerializerTestWithWasm : public ValueSerializerTest { |
+ public: |
+ ValueSerializerTestWithWasm() |
+ : deserialize_delegate_(&transfer_modules_), |
+ serialize_delegate_(&transfer_modules_) {} |
+ |
+ void Reset() { |
+ current_serializer_delegate_ = nullptr; |
+ current_deserializer_delegate_ = nullptr; |
+ } |
+ |
+ void EnableTransferSerialization() { |
+ current_serializer_delegate_ = &serialize_delegate_; |
+ } |
+ void EnableTransferDeserialization() { |
+ current_deserializer_delegate_ = &deserialize_delegate_; |
+ } |
+ void AllowInlineWasm(bool value) { |
+ deserialize_delegate_.SetAllowInlineWasm(value); |
+ } |
+ |
protected: |
static void SetUpTestCase() { |
g_saved_flag = i::FLAG_expose_wasm; |
@@ -2608,8 +2628,56 @@ class ValueSerializerTestWithWasm : public ValueSerializerTest { |
g_saved_flag = false; |
} |
+ class SerializeToTransfer : public ValueSerializer::Delegate { |
+ public: |
+ SerializeToTransfer( |
+ std::vector<WasmCompiledModule::TransferrableModule>* modules) |
+ : modules_(modules) {} |
+ Maybe<uint32_t> GetWasmModuleTransferId( |
+ Isolate* isolate, Local<WasmCompiledModule> module) override { |
+ modules_->push_back(module->AsTransferrableModule()); |
+ return Just(static_cast<uint32_t>(modules_->size()) - 1); |
+ } |
+ |
+ void ThrowDataCloneError(Local<String> message) override {} |
+ |
+ private: |
+ std::vector<WasmCompiledModule::TransferrableModule>* modules_; |
+ }; |
+ |
+ class DeserializeToTransfer : public ValueDeserializer::Delegate { |
+ public: |
+ DeserializeToTransfer( |
+ std::vector<WasmCompiledModule::TransferrableModule>* modules) |
+ : modules_(modules) {} |
+ |
+ MaybeLocal<WasmCompiledModule> GetWasmModuleFromId(Isolate* isolate, |
+ uint32_t id) override { |
+ return WasmCompiledModule::FromTransferrableModule(isolate, |
+ modules_->at(id)); |
+ } |
+ bool AllowInlineWasm() const override { return allow_inline_; } |
+ void SetAllowInlineWasm(bool value) { allow_inline_ = value; } |
+ |
+ private: |
+ std::vector<WasmCompiledModule::TransferrableModule>* modules_; |
+ bool allow_inline_ = false; |
+ }; |
+ |
+ ValueSerializer::Delegate* GetSerializerDelegate() override { |
+ return current_serializer_delegate_; |
+ } |
+ ValueDeserializer::Delegate* GetDeserializerDelegate() override { |
+ return current_deserializer_delegate_; |
+ } |
+ |
private: |
static bool g_saved_flag; |
+ std::vector<WasmCompiledModule::TransferrableModule> transfer_modules_; |
+ DeserializeToTransfer deserialize_delegate_; |
+ SerializeToTransfer serialize_delegate_; |
+ ValueSerializer::Delegate* current_serializer_delegate_ = nullptr; |
+ ValueDeserializer::Delegate* current_deserializer_delegate_ = nullptr; |
}; |
bool ValueSerializerTestWithWasm::g_saved_flag = false; |
@@ -2623,18 +2691,55 @@ const unsigned char kIncrementerWasm[] = { |
}; |
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")); |
- }); |
+ auto deserialize = [this]() { |
+ return WasmCompiledModule::DeserializeOrCompile( |
+ isolate(), {nullptr, 0}, |
+ {kIncrementerWasm, sizeof(kIncrementerWasm)}) |
+ .ToLocalChecked(); |
+ }; |
+ auto passingTest = [this, deserialize]() { |
+ RoundTripTest(deserialize, [this](Local<Value> value) { |
+ ASSERT_TRUE(value->IsWebAssemblyCompiledModule()); |
+ EXPECT_TRUE(EvaluateScriptForResultBool( |
+ "new WebAssembly.Instance(result).exports.increment(8) === 9")); |
+ }); |
+ }; |
+ |
+ auto failingTest = [this, deserialize]() { |
+ EncodeTest(deserialize, [this](const std::vector<uint8_t>& data) { |
+ InvalidDecodeTest(data); |
+ }); |
+ }; |
+ |
+ // We only want to allow deserialization through |
+ // transferred modules - which requres both serializer |
+ // and deserializer to understand that - or through |
+ // explicitly allowing inlined data, which requires |
+ // deserializer opt-in (we default the serializer to |
+ // inlined data because we don't trust that data on the |
+ // receiving end anyway). |
+ // |
+ // |
+ // Roundtripping works if serializer and |
+ // deserializer both work off transferred data |
+ Reset(); |
+ EnableTransferSerialization(); |
+ EnableTransferDeserialization(); |
+ passingTest(); |
+ // Alternatively, if the deserializer expects inline |
+ // data, and the serializer produces that - which is default |
+ Reset(); |
+ EnableTransferDeserialization(); |
+ AllowInlineWasm(true); |
+ passingTest(); |
+ // By default, the deserializer does not work with inlined |
+ // data |
+ Reset(); |
+ failingTest(); |
+ // Even if the serializer tries transferring, the deserializer |
+ // won't work. |
+ EnableTransferSerialization(); |
+ failingTest(); |
} |
// As produced around Chrome 56. |