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]; | |
viettrungluu
2016/03/30 17:49:01
Please initialize this (|= {}| is sufficient).
vardhan
2016/03/30 22:49:07
Done.
| |
105 EXPECT_FALSE(nd.Serialize(buf, sizeof(buf))); | |
106 | |
107 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.
| |
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]; | |
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.
| |
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); | |
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.
| |
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]; | |
viettrungluu
2016/03/30 17:49:01
"
vardhan
2016/03/30 22:49:07
Done.
| |
188 ContainsOther::Data_* co_data = reinterpret_cast<ContainsOther::Data_*>(buf); | |
189 ContainsOther co; | |
190 | |
191 // Success case. | |
192 co.other = kMagic; | |
193 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.
| |
194 EXPECT_TRUE(co.Serialize(buf, sizeof(buf))); | |
195 co.other = 0; | |
196 co.DeserializeWithoutValidation(buf); | |
197 EXPECT_EQ(kMagic, co.other); | |
198 | |
199 // Invalid struct header, but will pass (i.e., won't crash) anyway because we | |
200 // don't Validate. | |
201 co_data->header_.num_bytes = 0u; | |
202 co.DeserializeWithoutValidation(buf); | |
203 EXPECT_EQ(kMagic, co_data->other); | |
204 EXPECT_EQ(0u, co_data->header_.num_bytes); | |
205 } | |
206 | |
145 } // namespace | 207 } // namespace |
146 } // namespace test | 208 } // namespace test |
147 } // namespace mojo | 209 } // namespace mojo |
OLD | NEW |