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
3 // found in the LICENSE file.
4
5 #include <stddef.h>
6 #include <stdint.h>
7
8 #include <limits>
9
10 #include "mojo/public/cpp/bindings/lib/serialization_util.h"
11 #include "mojo/public/cpp/bindings/lib/validation_context.h"
12 #include "mojo/public/cpp/system/core.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 namespace mojo {
16 namespace test {
17 namespace {
18
19 using Handle_Data = mojo::internal::Handle_Data;
20 using AssociatedEndpointHandle_Data =
21 mojo::internal::AssociatedEndpointHandle_Data;
22
ToPtr(uintptr_t ptr)23 const void* ToPtr(uintptr_t ptr) {
24 return reinterpret_cast<const void*>(ptr);
25 }
26
27 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
TEST(ValidationContextTest,ConstructorRangeOverflow)28 TEST(ValidationContextTest, ConstructorRangeOverflow) {
29 {
30 // Test memory range overflow.
31 internal::ValidationContext context(
32 ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 5000, 0, 0);
33
34 EXPECT_FALSE(context.IsValidRange(
35 ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
36 EXPECT_FALSE(context.ClaimMemory(
37 ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
38 }
39
40 if (sizeof(size_t) <= sizeof(uint32_t))
41 return;
42
43 {
44 // Test handle index range overflow.
45 size_t num_handles =
46 static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5;
47 internal::ValidationContext context(ToPtr(0), 0, num_handles, 0);
48
49 EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
50 EXPECT_FALSE(context.ClaimHandle(
51 Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
52
53 EXPECT_TRUE(context.ClaimHandle(
54 Handle_Data(internal::kEncodedInvalidHandleValue)));
55 }
56
57 {
58 size_t num_associated_endpoint_handles =
59 static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5;
60 internal::ValidationContext context(ToPtr(0), 0, 0,
61 num_associated_endpoint_handles);
62
63 EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
64 AssociatedEndpointHandle_Data(0)));
65 EXPECT_FALSE(
66 context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data(
67 std::numeric_limits<uint32_t>::max() - 1)));
68
69 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
70 AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
71 }
72 }
73 #endif
74
TEST(ValidationContextTest,IsValidRange)75 TEST(ValidationContextTest, IsValidRange) {
76 {
77 internal::ValidationContext context(ToPtr(1234), 100, 0, 0);
78
79 // Basics.
80 EXPECT_FALSE(context.IsValidRange(ToPtr(100), 5));
81 EXPECT_FALSE(context.IsValidRange(ToPtr(1230), 50));
82 EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 5));
83 EXPECT_TRUE(context.IsValidRange(ToPtr(1240), 50));
84 EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 100));
85 EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 101));
86 EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 100));
87 EXPECT_FALSE(context.IsValidRange(ToPtr(1333), 5));
88 EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 5));
89
90 // ClaimMemory() updates the valid range.
91 EXPECT_TRUE(context.ClaimMemory(ToPtr(1254), 10));
92
93 EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
94 EXPECT_FALSE(context.IsValidRange(ToPtr(1254), 10));
95 EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 1));
96 EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 10));
97 EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 10));
98 EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 70));
99 EXPECT_FALSE(context.IsValidRange(ToPtr(1264), 71));
100 }
101
102 {
103 internal::ValidationContext context(ToPtr(1234), 100, 0, 0);
104 // Should return false for empty ranges.
105 EXPECT_FALSE(context.IsValidRange(ToPtr(0), 0));
106 EXPECT_FALSE(context.IsValidRange(ToPtr(1200), 0));
107 EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
108 EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 0));
109 EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 0));
110 }
111
112 {
113 // The valid memory range is empty.
114 internal::ValidationContext context(ToPtr(1234), 0, 0, 0);
115
116 EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
117 EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
118 }
119
120 {
121 internal::ValidationContext context(
122 ToPtr(std::numeric_limits<uintptr_t>::max() - 2000), 1000, 0, 0);
123
124 // Test overflow.
125 EXPECT_FALSE(context.IsValidRange(
126 ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 4000));
127 EXPECT_FALSE(context.IsValidRange(
128 ToPtr(std::numeric_limits<uintptr_t>::max() - 1500),
129 std::numeric_limits<uint32_t>::max()));
130
131 // This should be fine.
132 EXPECT_TRUE(context.IsValidRange(
133 ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 200));
134 }
135 }
136
TEST(ValidationContextTest,ClaimHandle)137 TEST(ValidationContextTest, ClaimHandle) {
138 {
139 internal::ValidationContext context(ToPtr(0), 0, 10, 0);
140
141 // Basics.
142 EXPECT_TRUE(context.ClaimHandle(Handle_Data(0)));
143 EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
144
145 EXPECT_TRUE(context.ClaimHandle(Handle_Data(9)));
146 EXPECT_FALSE(context.ClaimHandle(Handle_Data(10)));
147
148 // Should fail because it is smaller than the max index that has been
149 // claimed.
150 EXPECT_FALSE(context.ClaimHandle(Handle_Data(8)));
151
152 // Should return true for invalid handle.
153 EXPECT_TRUE(context.ClaimHandle(
154 Handle_Data(internal::kEncodedInvalidHandleValue)));
155 EXPECT_TRUE(context.ClaimHandle(
156 Handle_Data(internal::kEncodedInvalidHandleValue)));
157 }
158
159 {
160 // No handle to claim.
161 internal::ValidationContext context(ToPtr(0), 0, 0, 0);
162
163 EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
164
165 // Should still return true for invalid handle.
166 EXPECT_TRUE(context.ClaimHandle(
167 Handle_Data(internal::kEncodedInvalidHandleValue)));
168 }
169
170 {
171 // Test the case that |num_handles| is the same value as
172 // |internal::kEncodedInvalidHandleValue|.
173 EXPECT_EQ(internal::kEncodedInvalidHandleValue,
174 std::numeric_limits<uint32_t>::max());
175 internal::ValidationContext context(
176 ToPtr(0), 0, std::numeric_limits<uint32_t>::max(), 0);
177
178 EXPECT_TRUE(context.ClaimHandle(
179 Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
180 EXPECT_FALSE(context.ClaimHandle(
181 Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
182 EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
183
184 // Should still return true for invalid handle.
185 EXPECT_TRUE(context.ClaimHandle(
186 Handle_Data(internal::kEncodedInvalidHandleValue)));
187 }
188 }
189
TEST(ValidationContextTest,ClaimAssociatedEndpointHandle)190 TEST(ValidationContextTest, ClaimAssociatedEndpointHandle) {
191 {
192 internal::ValidationContext context(ToPtr(0), 0, 0, 10);
193
194 // Basics.
195 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
196 AssociatedEndpointHandle_Data(0)));
197 EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
198 AssociatedEndpointHandle_Data(0)));
199
200 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
201 AssociatedEndpointHandle_Data(9)));
202 EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
203 AssociatedEndpointHandle_Data(10)));
204
205 // Should fail because it is smaller than the max index that has been
206 // claimed.
207 EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
208 AssociatedEndpointHandle_Data(8)));
209
210 // Should return true for invalid handle.
211 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
212 AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
213 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
214 AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
215 }
216
217 {
218 // No handle to claim.
219 internal::ValidationContext context(ToPtr(0), 0, 0, 0);
220
221 EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
222 AssociatedEndpointHandle_Data(0)));
223
224 // Should still return true for invalid handle.
225 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
226 AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
227 }
228
229 {
230 // Test the case that |num_associated_endpoint_handles| is the same value as
231 // |internal::kEncodedInvalidHandleValue|.
232 EXPECT_EQ(internal::kEncodedInvalidHandleValue,
233 std::numeric_limits<uint32_t>::max());
234 internal::ValidationContext context(ToPtr(0), 0, 0,
235 std::numeric_limits<uint32_t>::max());
236
237 EXPECT_TRUE(
238 context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data(
239 std::numeric_limits<uint32_t>::max() - 1)));
240 EXPECT_FALSE(
241 context.ClaimAssociatedEndpointHandle(AssociatedEndpointHandle_Data(
242 std::numeric_limits<uint32_t>::max() - 1)));
243 EXPECT_FALSE(context.ClaimAssociatedEndpointHandle(
244 AssociatedEndpointHandle_Data(0)));
245
246 // Should still return true for invalid handle.
247 EXPECT_TRUE(context.ClaimAssociatedEndpointHandle(
248 AssociatedEndpointHandle_Data(internal::kEncodedInvalidHandleValue)));
249 }
250 }
251
TEST(ValidationContextTest,ClaimMemory)252 TEST(ValidationContextTest, ClaimMemory) {
253 {
254 internal::ValidationContext context(ToPtr(1000), 2000, 0, 0);
255
256 // Basics.
257 EXPECT_FALSE(context.ClaimMemory(ToPtr(500), 100));
258 EXPECT_FALSE(context.ClaimMemory(ToPtr(800), 300));
259 EXPECT_TRUE(context.ClaimMemory(ToPtr(1000), 100));
260 EXPECT_FALSE(context.ClaimMemory(ToPtr(1099), 100));
261 EXPECT_TRUE(context.ClaimMemory(ToPtr(1100), 200));
262 EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 1001));
263 EXPECT_TRUE(context.ClaimMemory(ToPtr(2000), 500));
264 EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 500));
265 EXPECT_FALSE(context.ClaimMemory(ToPtr(1400), 100));
266 EXPECT_FALSE(context.ClaimMemory(ToPtr(3000), 1));
267 EXPECT_TRUE(context.ClaimMemory(ToPtr(2500), 500));
268 }
269
270 {
271 // No memory to claim.
272 internal::ValidationContext context(ToPtr(10000), 0, 0, 0);
273
274 EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 1));
275 EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 0));
276 }
277
278 {
279 internal::ValidationContext context(
280 ToPtr(std::numeric_limits<uintptr_t>::max() - 1000), 500, 0, 0);
281
282 // Test overflow.
283 EXPECT_FALSE(context.ClaimMemory(
284 ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 4000));
285 EXPECT_FALSE(
286 context.ClaimMemory(ToPtr(std::numeric_limits<uintptr_t>::max() - 750),
287 std::numeric_limits<uint32_t>::max()));
288
289 // This should be fine.
290 EXPECT_TRUE(context.ClaimMemory(
291 ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 200));
292 }
293 }
294
295 } // namespace
296 } // namespace test
297 } // namespace mojo
298