Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: mojo/public/cpp/bindings/tests/serialization_api_unittest.cc

Issue 1800753005: C++ bindings: A struct's Deserialize() now does validation before deserializing. (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: fix char* - >char bug in unittest. FixedBuffer can accept sizes that aren't 8 byte multiples. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « mojo/public/cpp/bindings/tests/buffer_unittest.cc ('k') | mojo/public/cpp/bindings/tests/union_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698