• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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