OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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" |
| 6 #include "mojo/public/cpp/bindings/lib/array_internal.h" |
| 7 #include "mojo/public/cpp/bindings/lib/array_serialization.h" |
5 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" | 8 #include "mojo/public/cpp/bindings/lib/bounds_checker.h" |
6 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" | 9 #include "mojo/public/cpp/bindings/lib/fixed_buffer.h" |
7 #include "mojo/public/cpp/bindings/string.h" | 10 #include "mojo/public/cpp/bindings/string.h" |
8 #include "mojo/public/cpp/environment/environment.h" | 11 #include "mojo/public/cpp/environment/environment.h" |
| 12 #include "mojo/public/interfaces/bindings/tests/test_structs.mojom.h" |
9 #include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h" | 13 #include "mojo/public/interfaces/bindings/tests/test_unions.mojom.h" |
10 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
11 | 15 |
12 namespace mojo { | 16 namespace mojo { |
13 namespace test { | 17 namespace test { |
14 | 18 |
15 TEST(UnionTest, PlainOldDataGetterSetter) { | 19 TEST(UnionTest, PlainOldDataGetterSetter) { |
16 PodUnionPtr pod(PodUnion::New()); | 20 PodUnionPtr pod(PodUnion::New()); |
17 | 21 |
18 pod->set_f_int8(10); | 22 pod->set_f_int8(10); |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 PodUnionPtr pod_clone = pod.Clone(); | 101 PodUnionPtr pod_clone = pod.Clone(); |
98 EXPECT_EQ(10, pod_clone->get_f_int8()); | 102 EXPECT_EQ(10, pod_clone->get_f_int8()); |
99 EXPECT_TRUE(pod_clone->is_f_int8()); | 103 EXPECT_TRUE(pod_clone->is_f_int8()); |
100 EXPECT_EQ(pod_clone->which(), PodUnion::Tag::F_INT8); | 104 EXPECT_EQ(pod_clone->which(), PodUnion::Tag::F_INT8); |
101 } | 105 } |
102 | 106 |
103 TEST(UnionTest, SerializationPod) { | 107 TEST(UnionTest, SerializationPod) { |
104 PodUnionPtr pod1(PodUnion::New()); | 108 PodUnionPtr pod1(PodUnion::New()); |
105 pod1->set_f_int8(10); | 109 pod1->set_f_int8(10); |
106 | 110 |
107 size_t size = GetSerializedSize_(pod1); | 111 size_t size = GetSerializedSize_(pod1, false); |
108 EXPECT_EQ(16U, size); | 112 EXPECT_EQ(16U, size); |
109 | 113 |
110 mojo::internal::FixedBuffer buf(size); | 114 mojo::internal::FixedBuffer buf(size); |
111 internal::PodUnion_Data* data; | 115 internal::PodUnion_Data* data = nullptr; |
112 Serialize_(pod1.Pass(), &buf, &data); | 116 SerializeUnion_(pod1.Pass(), &buf, &data, false); |
113 | 117 |
114 PodUnionPtr pod2; | 118 PodUnionPtr pod2; |
115 Deserialize_(data, &pod2); | 119 Deserialize_(data, &pod2); |
116 | 120 |
117 EXPECT_EQ(10, pod2->get_f_int8()); | 121 EXPECT_EQ(10, pod2->get_f_int8()); |
118 EXPECT_TRUE(pod2->is_f_int8()); | 122 EXPECT_TRUE(pod2->is_f_int8()); |
119 EXPECT_EQ(pod2->which(), PodUnion::Tag::F_INT8); | 123 EXPECT_EQ(pod2->which(), PodUnion::Tag::F_INT8); |
120 } | 124 } |
121 | 125 |
122 TEST(UnionTest, ValidationJustWorksPod) { | 126 TEST(UnionTest, PodValidation) { |
123 PodUnionPtr pod(PodUnion::New()); | 127 PodUnionPtr pod(PodUnion::New()); |
124 pod->set_f_int8(10); | 128 pod->set_f_int8(10); |
125 | 129 |
126 size_t size = GetSerializedSize_(pod); | 130 size_t size = GetSerializedSize_(pod, false); |
127 EXPECT_EQ(16U, size); | 131 EXPECT_EQ(16U, size); |
128 | 132 |
129 mojo::internal::FixedBuffer buf(size); | 133 mojo::internal::FixedBuffer buf(size); |
130 internal::PodUnion_Data* data; | 134 internal::PodUnion_Data* data = nullptr; |
131 Serialize_(pod.Pass(), &buf, &data); | 135 SerializeUnion_(pod.Pass(), &buf, &data, false); |
132 void* raw_buf = buf.Leak(); | 136 void* raw_buf = buf.Leak(); |
133 mojo::internal::BoundsChecker bounds_checker(data, | 137 mojo::internal::BoundsChecker bounds_checker(data, |
134 static_cast<uint32_t>(size), 0); | 138 static_cast<uint32_t>(size), 0); |
135 EXPECT_TRUE(internal::PodUnion_Data::Validate(raw_buf, &bounds_checker)); | 139 EXPECT_TRUE( |
| 140 internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false)); |
136 free(raw_buf); | 141 free(raw_buf); |
137 } | 142 } |
138 | 143 |
| 144 TEST(UnionTest, SerializeNotNull) { |
| 145 PodUnionPtr pod(PodUnion::New()); |
| 146 pod->set_f_int8(0); |
| 147 size_t size = GetSerializedSize_(pod, false); |
| 148 mojo::internal::FixedBuffer buf(size); |
| 149 internal::PodUnion_Data* data = nullptr; |
| 150 SerializeUnion_(pod.Pass(), &buf, &data, false); |
| 151 EXPECT_FALSE(data->is_null()); |
| 152 } |
| 153 |
| 154 TEST(UnionTest, SerializeIsNullInlined) { |
| 155 PodUnionPtr pod; |
| 156 size_t size = GetSerializedSize_(pod, false); |
| 157 EXPECT_EQ(16U, size); |
| 158 mojo::internal::FixedBuffer buf(size); |
| 159 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); |
| 160 |
| 161 // Check that dirty output buffers are handled correctly by serialization. |
| 162 data->size = 16U; |
| 163 data->tag = PodUnion::Tag::F_UINT16; |
| 164 data->data.f_f_int16 = 20; |
| 165 |
| 166 SerializeUnion_(pod.Pass(), &buf, &data, true); |
| 167 EXPECT_TRUE(data->is_null()); |
| 168 |
| 169 PodUnionPtr pod2; |
| 170 Deserialize_(data, &pod2); |
| 171 EXPECT_TRUE(pod2.is_null()); |
| 172 } |
| 173 |
| 174 TEST(UnionTest, SerializeIsNullNotInlined) { |
| 175 PodUnionPtr pod; |
| 176 size_t size = GetSerializedSize_(pod, false); |
| 177 EXPECT_EQ(16U, size); |
| 178 mojo::internal::FixedBuffer buf(size); |
| 179 internal::PodUnion_Data* data = nullptr; |
| 180 SerializeUnion_(pod.Pass(), &buf, &data, false); |
| 181 EXPECT_EQ(nullptr, data); |
| 182 } |
| 183 |
139 TEST(UnionTest, NullValidation) { | 184 TEST(UnionTest, NullValidation) { |
140 void* buf = nullptr; | 185 void* buf = nullptr; |
141 mojo::internal::BoundsChecker bounds_checker(buf, 0, 0); | 186 mojo::internal::BoundsChecker bounds_checker(buf, 0, 0); |
142 EXPECT_TRUE(internal::PodUnion_Data::Validate(buf, &bounds_checker)); | 187 EXPECT_TRUE(internal::PodUnion_Data::Validate(buf, &bounds_checker, false)); |
143 } | 188 } |
144 | 189 |
145 TEST(UnionTest, OutOfAlignmentValidation) { | 190 TEST(UnionTest, OutOfAlignmentValidation) { |
146 Environment environment; | 191 Environment environment; |
147 size_t size = sizeof(internal::PodUnion_Data); | 192 size_t size = sizeof(internal::PodUnion_Data); |
148 // Get an aligned object and shift the alignment. | 193 // Get an aligned object and shift the alignment. |
149 mojo::internal::FixedBuffer aligned_buf(size + 1); | 194 mojo::internal::FixedBuffer aligned_buf(size + 1); |
150 void* raw_buf = aligned_buf.Leak(); | 195 void* raw_buf = aligned_buf.Leak(); |
151 char* buf = reinterpret_cast<char*>(raw_buf) + 1; | 196 char* buf = reinterpret_cast<char*>(raw_buf) + 1; |
152 | 197 |
153 internal::PodUnion_Data* data = | 198 internal::PodUnion_Data* data = |
154 reinterpret_cast<internal::PodUnion_Data*>(buf); | 199 reinterpret_cast<internal::PodUnion_Data*>(buf); |
155 mojo::internal::BoundsChecker bounds_checker(data, | 200 mojo::internal::BoundsChecker bounds_checker(data, |
156 static_cast<uint32_t>(size), 0); | 201 static_cast<uint32_t>(size), 0); |
157 EXPECT_FALSE(internal::PodUnion_Data::Validate(buf, &bounds_checker)); | 202 EXPECT_FALSE(internal::PodUnion_Data::Validate(buf, &bounds_checker, false)); |
158 free(raw_buf); | 203 free(raw_buf); |
159 } | 204 } |
160 | 205 |
161 TEST(UnionTest, OOBValidation) { | 206 TEST(UnionTest, OOBValidation) { |
162 Environment environment; | 207 Environment environment; |
163 size_t size = sizeof(internal::PodUnion_Data) - 1; | 208 size_t size = sizeof(internal::PodUnion_Data) - 1; |
164 mojo::internal::FixedBuffer buf(size); | 209 mojo::internal::FixedBuffer buf(size); |
165 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); | 210 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); |
166 mojo::internal::BoundsChecker bounds_checker(data, | 211 mojo::internal::BoundsChecker bounds_checker(data, |
167 static_cast<uint32_t>(size), 0); | 212 static_cast<uint32_t>(size), 0); |
168 void* raw_buf = buf.Leak(); | 213 void* raw_buf = buf.Leak(); |
169 EXPECT_FALSE(internal::PodUnion_Data::Validate(raw_buf, &bounds_checker)); | 214 EXPECT_FALSE( |
| 215 internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false)); |
170 free(raw_buf); | 216 free(raw_buf); |
171 } | 217 } |
172 | 218 |
173 TEST(UnionTest, UnknownTagValidation) { | 219 TEST(UnionTest, UnknownTagValidation) { |
174 Environment environment; | 220 Environment environment; |
175 size_t size = sizeof(internal::PodUnion_Data); | 221 size_t size = sizeof(internal::PodUnion_Data); |
176 mojo::internal::FixedBuffer buf(size); | 222 mojo::internal::FixedBuffer buf(size); |
177 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); | 223 internal::PodUnion_Data* data = internal::PodUnion_Data::New(&buf); |
178 data->tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(0xFFFFFF); | 224 data->tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(0xFFFFFF); |
179 mojo::internal::BoundsChecker bounds_checker(data, | 225 mojo::internal::BoundsChecker bounds_checker(data, |
180 static_cast<uint32_t>(size), 0); | 226 static_cast<uint32_t>(size), 0); |
181 void* raw_buf = buf.Leak(); | 227 void* raw_buf = buf.Leak(); |
182 EXPECT_FALSE(internal::PodUnion_Data::Validate(raw_buf, &bounds_checker)); | 228 EXPECT_FALSE( |
| 229 internal::PodUnion_Data::Validate(raw_buf, &bounds_checker, false)); |
183 free(raw_buf); | 230 free(raw_buf); |
184 } | 231 } |
185 | 232 |
186 TEST(UnionTest, StringGetterSetter) { | 233 TEST(UnionTest, StringGetterSetter) { |
187 ObjectUnionPtr pod(ObjectUnion::New()); | 234 ObjectUnionPtr pod(ObjectUnion::New()); |
188 | 235 |
189 String hello("hello world"); | 236 String hello("hello world"); |
190 pod->set_f_string(hello); | 237 pod->set_f_string(hello); |
191 EXPECT_EQ(hello, pod->get_f_string()); | 238 EXPECT_EQ(hello, pod->get_f_string()); |
192 EXPECT_TRUE(pod->is_f_string()); | 239 EXPECT_TRUE(pod->is_f_string()); |
(...skipping 22 matching lines...) Expand all Loading... |
215 EXPECT_TRUE(pod_clone->is_f_string()); | 262 EXPECT_TRUE(pod_clone->is_f_string()); |
216 EXPECT_EQ(pod_clone->which(), ObjectUnion::Tag::F_STRING); | 263 EXPECT_EQ(pod_clone->which(), ObjectUnion::Tag::F_STRING); |
217 } | 264 } |
218 | 265 |
219 TEST(UnionTest, StringSerialization) { | 266 TEST(UnionTest, StringSerialization) { |
220 ObjectUnionPtr pod1(ObjectUnion::New()); | 267 ObjectUnionPtr pod1(ObjectUnion::New()); |
221 | 268 |
222 String hello("hello world"); | 269 String hello("hello world"); |
223 pod1->set_f_string(hello); | 270 pod1->set_f_string(hello); |
224 | 271 |
225 size_t size = GetSerializedSize_(pod1); | 272 size_t size = GetSerializedSize_(pod1, false); |
226 mojo::internal::FixedBuffer buf(size); | 273 mojo::internal::FixedBuffer buf(size); |
227 internal::ObjectUnion_Data* data; | 274 internal::ObjectUnion_Data* data = nullptr; |
228 Serialize_(pod1.Pass(), &buf, &data); | 275 SerializeUnion_(pod1.Pass(), &buf, &data, false); |
229 | 276 |
230 ObjectUnionPtr pod2; | 277 ObjectUnionPtr pod2; |
231 Deserialize_(data, &pod2); | 278 Deserialize_(data, &pod2); |
232 EXPECT_EQ(hello, pod2->get_f_string()); | 279 EXPECT_EQ(hello, pod2->get_f_string()); |
233 EXPECT_TRUE(pod2->is_f_string()); | 280 EXPECT_TRUE(pod2->is_f_string()); |
234 EXPECT_EQ(pod2->which(), ObjectUnion::Tag::F_STRING); | 281 EXPECT_EQ(pod2->which(), ObjectUnion::Tag::F_STRING); |
235 } | 282 } |
236 | 283 |
237 TEST(UnionTest, StringValidationNull) { | 284 TEST(UnionTest, NullStringValidation) { |
238 Environment environment; | 285 Environment environment; |
239 size_t size = sizeof(internal::ObjectUnion_Data); | 286 size_t size = sizeof(internal::ObjectUnion_Data); |
240 mojo::internal::FixedBuffer buf(size); | 287 mojo::internal::FixedBuffer buf(size); |
241 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); | 288 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); |
242 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; | 289 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; |
243 data->data.unknown = 0x0; | 290 data->data.unknown = 0x0; |
244 mojo::internal::BoundsChecker bounds_checker(data, | 291 mojo::internal::BoundsChecker bounds_checker(data, |
245 static_cast<uint32_t>(size), 0); | 292 static_cast<uint32_t>(size), 0); |
246 void* raw_buf = buf.Leak(); | 293 void* raw_buf = buf.Leak(); |
247 EXPECT_FALSE(internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker)); | 294 EXPECT_FALSE( |
| 295 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, false)); |
248 free(raw_buf); | 296 free(raw_buf); |
249 } | 297 } |
250 | 298 |
251 TEST(UnionTest, StringValidationPointerOverflow) { | 299 TEST(UnionTest, StringPointerOverflowValidation) { |
252 Environment environment; | 300 Environment environment; |
253 size_t size = sizeof(internal::ObjectUnion_Data); | 301 size_t size = sizeof(internal::ObjectUnion_Data); |
254 mojo::internal::FixedBuffer buf(size); | 302 mojo::internal::FixedBuffer buf(size); |
255 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); | 303 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); |
256 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; | 304 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; |
257 data->data.unknown = 0xFFFFFFFFFFFFFFFF; | 305 data->data.unknown = 0xFFFFFFFFFFFFFFFF; |
258 mojo::internal::BoundsChecker bounds_checker(data, | 306 mojo::internal::BoundsChecker bounds_checker(data, |
259 static_cast<uint32_t>(size), 0); | 307 static_cast<uint32_t>(size), 0); |
260 void* raw_buf = buf.Leak(); | 308 void* raw_buf = buf.Leak(); |
261 EXPECT_FALSE(internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker)); | 309 EXPECT_FALSE( |
| 310 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, false)); |
262 free(raw_buf); | 311 free(raw_buf); |
263 } | 312 } |
264 | 313 |
265 TEST(UnionTest, StringValidationValidateString) { | 314 TEST(UnionTest, StringValidateOOB) { |
266 Environment environment; | 315 Environment environment; |
267 size_t size = 32; | 316 size_t size = 32; |
268 mojo::internal::FixedBuffer buf(size); | 317 mojo::internal::FixedBuffer buf(size); |
269 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); | 318 internal::ObjectUnion_Data* data = internal::ObjectUnion_Data::New(&buf); |
270 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; | 319 data->tag = internal::ObjectUnion_Data::ObjectUnion_Tag::F_STRING; |
271 | 320 |
272 data->data.f_f_string = 8; | 321 data->data.f_f_string = 8; |
273 char* ptr = reinterpret_cast<char*>(&data->data.f_f_string); | 322 char* ptr = reinterpret_cast<char*>(&data->data.f_f_string); |
274 mojo::internal::ArrayHeader* array_header = | 323 mojo::internal::ArrayHeader* array_header = |
275 reinterpret_cast<mojo::internal::ArrayHeader*>(ptr + *ptr); | 324 reinterpret_cast<mojo::internal::ArrayHeader*>(ptr + *ptr); |
276 array_header->num_bytes = 20; // This should go out of bounds. | 325 array_header->num_bytes = 20; // This should go out of bounds. |
277 array_header->num_elements = 20; | 326 array_header->num_elements = 20; |
278 mojo::internal::BoundsChecker bounds_checker(data, 32, 0); | 327 mojo::internal::BoundsChecker bounds_checker(data, 32, 0); |
279 void* raw_buf = buf.Leak(); | 328 void* raw_buf = buf.Leak(); |
280 EXPECT_FALSE(internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker)); | 329 EXPECT_FALSE( |
281 free(raw_buf); | 330 internal::ObjectUnion_Data::Validate(raw_buf, &bounds_checker, false)); |
282 } | 331 free(raw_buf); |
| 332 } |
| 333 |
| 334 // TODO(azani): Move back in array_unittest.cc when possible. |
| 335 // Array tests |
| 336 TEST(UnionTest, PodUnionInArray) { |
| 337 SmallStructPtr small_struct(SmallStruct::New()); |
| 338 small_struct->pod_union_array = Array<PodUnionPtr>(2); |
| 339 small_struct->pod_union_array[0] = PodUnion::New(); |
| 340 small_struct->pod_union_array[1] = PodUnion::New(); |
| 341 |
| 342 small_struct->pod_union_array[0]->set_f_int8(10); |
| 343 small_struct->pod_union_array[1]->set_f_int16(12); |
| 344 |
| 345 EXPECT_EQ(10, small_struct->pod_union_array[0]->get_f_int8()); |
| 346 EXPECT_EQ(12, small_struct->pod_union_array[1]->get_f_int16()); |
| 347 } |
| 348 |
| 349 TEST(UnionTest, PodUnionInArraySerialization) { |
| 350 Environment environment; |
| 351 Array<PodUnionPtr> array(2); |
| 352 array[0] = PodUnion::New(); |
| 353 array[1] = PodUnion::New(); |
| 354 |
| 355 array[0]->set_f_int8(10); |
| 356 array[1]->set_f_int16(12); |
| 357 EXPECT_EQ(2U, array.size()); |
| 358 |
| 359 size_t size = GetSerializedSize_(array); |
| 360 EXPECT_EQ(40U, size); |
| 361 |
| 362 mojo::internal::FixedBuffer buf(size); |
| 363 mojo::internal::Array_Data<internal::PodUnion_Data>* data; |
| 364 SerializeArray_<mojo::internal::ArrayValidateParams< |
| 365 0, false, mojo::internal::NoValidateParams>>(array.Pass(), &buf, &data); |
| 366 |
| 367 Array<PodUnionPtr> array2; |
| 368 Deserialize_(data, &array2); |
| 369 |
| 370 EXPECT_EQ(2U, array2.size()); |
| 371 |
| 372 EXPECT_EQ(10, array2[0]->get_f_int8()); |
| 373 EXPECT_EQ(12, array2[1]->get_f_int16()); |
| 374 } |
| 375 |
| 376 TEST(UnionTest, PodUnionInArraySerializationWithNull) { |
| 377 Environment environment; |
| 378 Array<PodUnionPtr> array(2); |
| 379 array[0] = PodUnion::New(); |
| 380 |
| 381 array[0]->set_f_int8(10); |
| 382 EXPECT_EQ(2U, array.size()); |
| 383 |
| 384 size_t size = GetSerializedSize_(array); |
| 385 EXPECT_EQ(40U, size); |
| 386 |
| 387 mojo::internal::FixedBuffer buf(size); |
| 388 mojo::internal::Array_Data<internal::PodUnion_Data>* data; |
| 389 SerializeArray_<mojo::internal::ArrayValidateParams< |
| 390 0, true, mojo::internal::NoValidateParams>>(array.Pass(), &buf, &data); |
| 391 |
| 392 Array<PodUnionPtr> array2; |
| 393 Deserialize_(data, &array2); |
| 394 |
| 395 EXPECT_EQ(2U, array2.size()); |
| 396 |
| 397 EXPECT_EQ(10, array2[0]->get_f_int8()); |
| 398 EXPECT_TRUE(array2[1].is_null()); |
| 399 } |
| 400 |
| 401 // TODO(azani): Move back in struct_unittest.cc when possible. |
| 402 // Struct tests |
| 403 TEST(UnionTest, Clone_Union) { |
| 404 Environment environment; |
| 405 SmallStructPtr small_struct(SmallStruct::New()); |
| 406 small_struct->pod_union = PodUnion::New(); |
| 407 small_struct->pod_union->set_f_int8(10); |
| 408 |
| 409 SmallStructPtr clone = small_struct.Clone(); |
| 410 EXPECT_EQ(10, clone->pod_union->get_f_int8()); |
| 411 } |
| 412 |
| 413 // Serialization test of a struct with a union of plain old data. |
| 414 TEST(UnionTest, Serialization_UnionOfPods) { |
| 415 Environment environment; |
| 416 SmallStructPtr small_struct(SmallStruct::New()); |
| 417 small_struct->pod_union = PodUnion::New(); |
| 418 small_struct->pod_union->set_f_int32(10); |
| 419 |
| 420 size_t size = GetSerializedSize_(small_struct); |
| 421 |
| 422 mojo::internal::FixedBuffer buf(size); |
| 423 internal::SmallStruct_Data* data = nullptr; |
| 424 Serialize_(small_struct.Pass(), &buf, &data); |
| 425 |
| 426 SmallStructPtr deserialized; |
| 427 Deserialize_(data, &deserialized); |
| 428 |
| 429 EXPECT_EQ(10, deserialized->pod_union->get_f_int32()); |
| 430 } |
| 431 |
| 432 // Serialization test of a struct with a union of structs. |
| 433 TEST(UnionTest, Serialization_UnionOfObjects) { |
| 434 Environment environment; |
| 435 SmallObjStructPtr obj_struct(SmallObjStruct::New()); |
| 436 obj_struct->obj_union = ObjectUnion::New(); |
| 437 String hello("hello world"); |
| 438 obj_struct->obj_union->set_f_string(hello); |
| 439 |
| 440 size_t size = GetSerializedSize_(obj_struct); |
| 441 |
| 442 mojo::internal::FixedBuffer buf(size); |
| 443 internal::SmallObjStruct_Data* data = nullptr; |
| 444 Serialize_(obj_struct.Pass(), &buf, &data); |
| 445 |
| 446 SmallObjStructPtr deserialized; |
| 447 Deserialize_(data, &deserialized); |
| 448 |
| 449 EXPECT_EQ(hello, deserialized->obj_union->get_f_string()); |
| 450 } |
| 451 |
| 452 // Validation test of a struct with a union. |
| 453 TEST(UnionTest, Validation_UnionsInStruct) { |
| 454 Environment environment; |
| 455 SmallStructPtr small_struct(SmallStruct::New()); |
| 456 small_struct->pod_union = PodUnion::New(); |
| 457 small_struct->pod_union->set_f_int32(10); |
| 458 |
| 459 size_t size = GetSerializedSize_(small_struct); |
| 460 |
| 461 mojo::internal::FixedBuffer buf(size); |
| 462 internal::SmallStruct_Data* data = nullptr; |
| 463 Serialize_(small_struct.Pass(), &buf, &data); |
| 464 |
| 465 void* raw_buf = buf.Leak(); |
| 466 mojo::internal::BoundsChecker bounds_checker(data, size, 0); |
| 467 EXPECT_TRUE(internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker)); |
| 468 free(raw_buf); |
| 469 } |
| 470 |
| 471 // Validation test of a struct union fails due to unknown union tag. |
| 472 TEST(UnionTest, Validation_PodUnionInStruct_Failure) { |
| 473 Environment environment; |
| 474 SmallStructPtr small_struct(SmallStruct::New()); |
| 475 small_struct->pod_union = PodUnion::New(); |
| 476 small_struct->pod_union->set_f_int32(10); |
| 477 |
| 478 size_t size = GetSerializedSize_(small_struct); |
| 479 |
| 480 mojo::internal::FixedBuffer buf(size); |
| 481 internal::SmallStruct_Data* data = nullptr; |
| 482 Serialize_(small_struct.Pass(), &buf, &data); |
| 483 data->pod_union.tag = static_cast<internal::PodUnion_Data::PodUnion_Tag>(100); |
| 484 |
| 485 void* raw_buf = buf.Leak(); |
| 486 mojo::internal::BoundsChecker bounds_checker(data, size, 0); |
| 487 EXPECT_FALSE(internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker)); |
| 488 free(raw_buf); |
| 489 } |
| 490 |
| 491 // Validation fails due to non-nullable null union in struct. |
| 492 TEST(UnionTest, Validation_NullUnion_Failure) { |
| 493 Environment environment; |
| 494 SmallStructNonNullableUnionPtr small_struct( |
| 495 SmallStructNonNullableUnion::New()); |
| 496 |
| 497 size_t size = GetSerializedSize_(small_struct); |
| 498 |
| 499 mojo::internal::FixedBuffer buf(size); |
| 500 internal::SmallStructNonNullableUnion_Data* data = |
| 501 internal::SmallStructNonNullableUnion_Data::New(&buf); |
| 502 |
| 503 void* raw_buf = buf.Leak(); |
| 504 mojo::internal::BoundsChecker bounds_checker(data, size, 0); |
| 505 EXPECT_FALSE(internal::SmallStructNonNullableUnion_Data::Validate( |
| 506 raw_buf, &bounds_checker)); |
| 507 free(raw_buf); |
| 508 } |
| 509 |
| 510 // Validation passes with nullable null union. |
| 511 TEST(UnionTest, Validation_NullableUnion) { |
| 512 Environment environment; |
| 513 SmallStructPtr small_struct(SmallStruct::New()); |
| 514 |
| 515 size_t size = GetSerializedSize_(small_struct); |
| 516 |
| 517 mojo::internal::FixedBuffer buf(size); |
| 518 internal::SmallStruct_Data* data = nullptr; |
| 519 Serialize_(small_struct.Pass(), &buf, &data); |
| 520 |
| 521 void* raw_buf = buf.Leak(); |
| 522 mojo::internal::BoundsChecker bounds_checker(data, size, 0); |
| 523 EXPECT_TRUE(internal::SmallStruct_Data::Validate(raw_buf, &bounds_checker)); |
| 524 free(raw_buf); |
| 525 } |
| 526 |
283 } // namespace test | 527 } // namespace test |
284 } // namespace mojo | 528 } // namespace mojo |
OLD | NEW |