Chromium Code Reviews| Index: mojo/public/cpp/bindings/tests/serialization_api_unittest.cc |
| diff --git a/mojo/public/cpp/bindings/tests/serialization_api_unittest.cc b/mojo/public/cpp/bindings/tests/serialization_api_unittest.cc |
| index 28ada48a0609dc46c2422c27d222d6870e346c70..1f65b8cf91b0928cb91918f951bc53ef58be0ed6 100644 |
| --- a/mojo/public/cpp/bindings/tests/serialization_api_unittest.cc |
| +++ b/mojo/public/cpp/bindings/tests/serialization_api_unittest.cc |
| @@ -23,25 +23,29 @@ class StructSerializationAPITest : public testing::Test { |
| void SerializeAndDeserialize( |
| Type* val, |
| mojo::internal::ValidationError expected_validation_error) { |
| + size_t bytes_written = 0; |
| size_t num_bytes = val->GetSerializedSize(); |
| std::vector<uint8_t> bytes(num_bytes + 1); |
| // Last byte is a magic value, helps catch a buffer overflow for |
| // serialization. |
| bytes[num_bytes] = 170; |
| - val->Serialize(bytes.data(), num_bytes); |
| + val->Serialize(bytes.data(), num_bytes, &bytes_written); |
| EXPECT_EQ(170u, bytes[num_bytes]); |
| + EXPECT_EQ(num_bytes, bytes_written); |
| mojo::internal::BoundsChecker bounds_checker(bytes.data(), num_bytes, 0); |
| auto actual_validation_error = |
| Type::Data_::Validate(bytes.data(), &bounds_checker, nullptr); |
| EXPECT_EQ(expected_validation_error, actual_validation_error); |
| + Type out_val; |
| + bool deserialize_ret = out_val.Deserialize(bytes.data(), bytes.size()); |
| if (actual_validation_error == mojo::internal::ValidationError::NONE) { |
| - Type out_val; |
| - out_val.Deserialize(bytes.data()); |
| EXPECT_TRUE(val->Equals(out_val)); |
| } |
| + EXPECT_EQ(actual_validation_error == mojo::internal::ValidationError::NONE, |
| + deserialize_ret); |
| } |
| private: |
| @@ -90,6 +94,23 @@ TEST_F(StructSerializationAPITest, BasicStructSerialization) { |
| SerializeAndDeserialize(&default_values, |
| mojo::internal::ValidationError::NONE); |
| } |
| + |
| + { |
| + SCOPED_TRACE("NoDefaultFieldValues.Serialize() should fail"); |
| + NoDefaultFieldValues nd; |
| + nd.f0 = true; |
| + nd.f23 = mojo::Array<mojo::String>::New(10); |
| + |
| + char buf[1000]; |
|
viettrungluu
2016/03/30 17:49:01
Please initialize this (|= {}| is sufficient).
vardhan
2016/03/30 22:49:07
Done.
|
| + EXPECT_FALSE(nd.Serialize(buf, sizeof(buf))); |
| + |
| + size_t bytes_written; |
|
viettrungluu
2016/03/30 17:49:01
Please initialize this, preferably to something th
vardhan
2016/03/30 22:49:07
Done.
|
| + EXPECT_FALSE(nd.Serialize(buf, sizeof(buf), &bytes_written)); |
| + EXPECT_EQ(160UL, bytes_written); |
| + // The Serialize() shouldn't get around to reserving space for the |f23| |
| + // array field. |
| + EXPECT_LT(bytes_written, nd.GetSerializedSize()); |
| + } |
| } |
| // This tests serialization of handles -- These should be deaths or |
| @@ -142,6 +163,47 @@ TEST_F(StructSerializationAPITest, NullableHandleSerialization) { |
| mojo::internal::ValidationError::NONE); |
| } |
| +// Test that |Deserialize()| appropriately fails on validation. |
| +TEST_F(StructSerializationAPITest, DeserializationFailure) { |
| + char* buf[100]; |
|
viettrungluu
2016/03/30 17:49:01
a) Why is this an array of pointers?
b) Please ini
vardhan
2016/03/30 22:49:07
Oops! thanks for catching this, bad typo.
|
| + EmptyStruct es; |
| + |
| + // Bounds checker should fail this, since buf_size is too small. |
| + EXPECT_FALSE(es.Deserialize(buf, 1)); |
| + |
| + es.Serialize(buf, sizeof(buf)); |
| + EXPECT_TRUE(es.Deserialize(buf, sizeof(buf))); |
| + |
| + // Invalid struct header: this should happen inside |
| + // EmptyStruct::Data_::Validate()). |
| + es.Serialize(buf, sizeof(buf)); |
| + EmptyStruct::Data_* es_data = reinterpret_cast<EmptyStruct::Data_*>(buf); |
|
viettrungluu
2016/03/30 17:49:01
buf being an array of char*'s makes this UB.
vardhan
2016/03/30 22:49:07
Acknowledged.
|
| + es_data->header_.num_bytes = 0; |
| + EXPECT_FALSE(es.Deserialize(buf, sizeof(buf))); |
| +} |
| + |
| +TEST_F(StructSerializationAPITest, DeserializationWithoutValidation) { |
| + const int32_t kMagic = 456; |
| + char* buf[100]; |
|
viettrungluu
2016/03/30 17:49:01
"
vardhan
2016/03/30 22:49:07
Done.
|
| + ContainsOther::Data_* co_data = reinterpret_cast<ContainsOther::Data_*>(buf); |
| + ContainsOther co; |
| + |
| + // Success case. |
| + co.other = kMagic; |
| + memset(buf, 0, sizeof(buf)); |
|
viettrungluu
2016/03/30 17:49:01
And by initializing, you can skip this.
vardhan
2016/03/30 22:49:07
Done.
|
| + EXPECT_TRUE(co.Serialize(buf, sizeof(buf))); |
| + co.other = 0; |
| + co.DeserializeWithoutValidation(buf); |
| + EXPECT_EQ(kMagic, co.other); |
| + |
| + // Invalid struct header, but will pass (i.e., won't crash) anyway because we |
| + // don't Validate. |
| + co_data->header_.num_bytes = 0u; |
| + co.DeserializeWithoutValidation(buf); |
| + EXPECT_EQ(kMagic, co_data->other); |
| + EXPECT_EQ(0u, co_data->header_.num_bytes); |
| +} |
| + |
| } // namespace |
| } // namespace test |
| } // namespace mojo |