OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "mojo/public/cpp/bindings/array.h" | 5 #include "mojo/public/cpp/bindings/array.h" |
6 #include "mojo/public/cpp/bindings/lib/array_serialization.h" | 6 #include "mojo/public/cpp/bindings/lib/array_serialization.h" |
7 #include "mojo/public/cpp/bindings/lib/validation_errors.h" | 7 #include "mojo/public/cpp/bindings/lib/validation_errors.h" |
8 #include "mojo/public/cpp/system/message_pipe.h" | 8 #include "mojo/public/cpp/system/message_pipe.h" |
9 #include "mojo/public/interfaces/bindings/tests/rect.mojom.h" | 9 #include "mojo/public/interfaces/bindings/tests/rect.mojom.h" |
10 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" | 10 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" |
11 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
12 | 12 |
13 namespace mojo { | 13 namespace mojo { |
14 namespace test { | 14 namespace test { |
15 namespace { | 15 namespace { |
16 | 16 |
17 class StructSerializationAPITest : public testing::Test { | 17 class StructSerializationAPITest : public testing::Test { |
18 public: | 18 public: |
19 // We Serialize and Deserialize the given |Type|, and expect the given | 19 // We Serialize and Deserialize the given |Type|, and expect the given |
20 // serialization warnings. We also validate (and expect a given error) in | 20 // serialization warnings. We also validate (and expect a given error) in |
21 // between serialization and deserialization. | 21 // between serialization and deserialization. |
22 template <typename Type> | 22 template <typename Type> |
23 void SerializeAndDeserialize( | 23 void SerializeAndDeserialize( |
24 Type* val, | 24 Type* val, |
25 mojo::internal::ValidationError expected_validation_error) { | 25 mojo::internal::ValidationError expected_validation_error) { |
| 26 size_t bytes_written = 0; |
26 size_t num_bytes = val->GetSerializedSize(); | 27 size_t num_bytes = val->GetSerializedSize(); |
27 std::vector<uint8_t> bytes(num_bytes + 1); | 28 std::vector<uint8_t> bytes(num_bytes + 1); |
28 | 29 |
29 // Last byte is a magic value, helps catch a buffer overflow for | 30 // Last byte is a magic value, helps catch a buffer overflow for |
30 // serialization. | 31 // serialization. |
31 bytes[num_bytes] = 170; | 32 bytes[num_bytes] = 170; |
32 val->Serialize(bytes.data(), num_bytes); | 33 val->Serialize(bytes.data(), num_bytes, &bytes_written); |
33 EXPECT_EQ(170u, bytes[num_bytes]); | 34 EXPECT_EQ(170u, bytes[num_bytes]); |
| 35 EXPECT_EQ(num_bytes, bytes_written); |
34 | 36 |
35 mojo::internal::BoundsChecker bounds_checker(bytes.data(), num_bytes, 0); | 37 mojo::internal::BoundsChecker bounds_checker(bytes.data(), num_bytes, 0); |
36 auto actual_validation_error = | 38 auto actual_validation_error = |
37 Type::Data_::Validate(bytes.data(), &bounds_checker, nullptr); | 39 Type::Data_::Validate(bytes.data(), &bounds_checker, nullptr); |
38 EXPECT_EQ(expected_validation_error, actual_validation_error); | 40 EXPECT_EQ(expected_validation_error, actual_validation_error); |
39 | 41 |
| 42 Type out_val; |
| 43 bool deserialize_ret = out_val.Deserialize(bytes.data(), bytes.size()); |
40 if (actual_validation_error == mojo::internal::ValidationError::NONE) { | 44 if (actual_validation_error == mojo::internal::ValidationError::NONE) { |
41 Type out_val; | |
42 out_val.Deserialize(bytes.data()); | |
43 EXPECT_TRUE(val->Equals(out_val)); | 45 EXPECT_TRUE(val->Equals(out_val)); |
44 } | 46 } |
| 47 EXPECT_EQ(actual_validation_error == mojo::internal::ValidationError::NONE, |
| 48 deserialize_ret); |
45 } | 49 } |
46 | 50 |
47 private: | 51 private: |
48 Environment env_; | 52 Environment env_; |
49 }; | 53 }; |
50 | 54 |
51 TEST_F(StructSerializationAPITest, GetSerializedSize) { | 55 TEST_F(StructSerializationAPITest, GetSerializedSize) { |
52 Rect rect; | 56 Rect rect; |
53 // 8 byte struct header | 57 // 8 byte struct header |
54 // + 16 bytes worth of fields | 58 // + 16 bytes worth of fields |
(...skipping 28 matching lines...) Expand all Loading... |
83 rect.height = 999; | 87 rect.height = 999; |
84 SerializeAndDeserialize(&rect, mojo::internal::ValidationError::NONE); | 88 SerializeAndDeserialize(&rect, mojo::internal::ValidationError::NONE); |
85 } | 89 } |
86 | 90 |
87 { | 91 { |
88 SCOPED_TRACE("DefaultFieldValues"); | 92 SCOPED_TRACE("DefaultFieldValues"); |
89 DefaultFieldValues default_values; | 93 DefaultFieldValues default_values; |
90 SerializeAndDeserialize(&default_values, | 94 SerializeAndDeserialize(&default_values, |
91 mojo::internal::ValidationError::NONE); | 95 mojo::internal::ValidationError::NONE); |
92 } | 96 } |
| 97 |
| 98 { |
| 99 SCOPED_TRACE("NoDefaultFieldValues.Serialize() should fail"); |
| 100 NoDefaultFieldValues nd; |
| 101 nd.f0 = true; |
| 102 nd.f23 = mojo::Array<mojo::String>::New(10); |
| 103 |
| 104 char buf[1000] = {}; |
| 105 EXPECT_FALSE(nd.Serialize(buf, sizeof(buf))); |
| 106 |
| 107 size_t bytes_written = 0; |
| 108 EXPECT_FALSE(nd.Serialize(buf, sizeof(buf), &bytes_written)); |
| 109 EXPECT_EQ(160UL, bytes_written); |
| 110 // The Serialize() shouldn't get around to reserving space for the |f23| |
| 111 // array field. |
| 112 EXPECT_LT(bytes_written, nd.GetSerializedSize()); |
| 113 } |
93 } | 114 } |
94 | 115 |
95 // This tests serialization of handles -- These should be deaths or | 116 // This tests serialization of handles -- These should be deaths or |
96 TEST_F(StructSerializationAPITest, HandlesSerialization) { | 117 TEST_F(StructSerializationAPITest, HandlesSerialization) { |
97 { | 118 { |
98 SCOPED_TRACE("Uninitialized Array"); | 119 SCOPED_TRACE("Uninitialized Array"); |
99 HandleStruct handle_struct; | 120 HandleStruct handle_struct; |
100 // TODO(vardhan): Once handles and pointers are encoded inline with | 121 // TODO(vardhan): Once handles and pointers are encoded inline with |
101 // serialization, validation should fail at | 122 // serialization, validation should fail at |
102 // ValidationError::UNEXPECTED_NULL_POINTER (which happens after the | 123 // ValidationError::UNEXPECTED_NULL_POINTER (which happens after the |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
135 | 156 |
136 // We should be able to Serialize/Deserialize a struct that has a nullable | 157 // We should be able to Serialize/Deserialize a struct that has a nullable |
137 // handle which is null. | 158 // handle which is null. |
138 TEST_F(StructSerializationAPITest, NullableHandleSerialization) { | 159 TEST_F(StructSerializationAPITest, NullableHandleSerialization) { |
139 NullableHandleStruct handle_struct; | 160 NullableHandleStruct handle_struct; |
140 handle_struct.data = 16; | 161 handle_struct.data = 16; |
141 SerializeAndDeserialize(&handle_struct, | 162 SerializeAndDeserialize(&handle_struct, |
142 mojo::internal::ValidationError::NONE); | 163 mojo::internal::ValidationError::NONE); |
143 } | 164 } |
144 | 165 |
| 166 // Test that |Deserialize()| appropriately fails on validation. |
| 167 TEST_F(StructSerializationAPITest, DeserializationFailure) { |
| 168 char buf[100] = {}; |
| 169 EmptyStruct es; |
| 170 |
| 171 // Bounds checker should fail this, since buf_size is too small. |
| 172 EXPECT_FALSE(es.Deserialize(buf, 1)); |
| 173 |
| 174 es.Serialize(buf, sizeof(buf)); |
| 175 EXPECT_TRUE(es.Deserialize(buf, sizeof(buf))); |
| 176 |
| 177 // Invalid struct header: this should happen inside |
| 178 // EmptyStruct::Data_::Validate()). |
| 179 es.Serialize(buf, sizeof(buf)); |
| 180 EmptyStruct::Data_* es_data = reinterpret_cast<EmptyStruct::Data_*>(buf); |
| 181 es_data->header_.num_bytes = 0; |
| 182 EXPECT_FALSE(es.Deserialize(buf, sizeof(buf))); |
| 183 } |
| 184 |
| 185 TEST_F(StructSerializationAPITest, DeserializationWithoutValidation) { |
| 186 const int32_t kMagic = 456; |
| 187 char buf[100] = {}; |
| 188 ContainsOther::Data_* co_data = reinterpret_cast<ContainsOther::Data_*>(buf); |
| 189 ContainsOther co; |
| 190 |
| 191 // Success case. |
| 192 co.other = kMagic; |
| 193 EXPECT_TRUE(co.Serialize(buf, sizeof(buf))); |
| 194 co.other = 0; |
| 195 co.DeserializeWithoutValidation(buf); |
| 196 EXPECT_EQ(kMagic, co.other); |
| 197 |
| 198 // Invalid struct header, but will pass (i.e., won't crash) anyway because we |
| 199 // don't Validate. |
| 200 co_data->header_.num_bytes = 0u; |
| 201 co.DeserializeWithoutValidation(buf); |
| 202 EXPECT_EQ(kMagic, co_data->other); |
| 203 EXPECT_EQ(0u, co_data->header_.num_bytes); |
| 204 } |
| 205 |
145 } // namespace | 206 } // namespace |
146 } // namespace test | 207 } // namespace test |
147 } // namespace mojo | 208 } // namespace mojo |
OLD | NEW |