• 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 
ToPtr(uintptr_t ptr)21 const void* ToPtr(uintptr_t ptr) {
22   return reinterpret_cast<const void*>(ptr);
23 }
24 
25 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON)
TEST(ValidationContextTest,ConstructorRangeOverflow)26 TEST(ValidationContextTest, ConstructorRangeOverflow) {
27   {
28     // Test memory range overflow.
29     internal::ValidationContext context(
30         ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 5000, 0);
31 
32     EXPECT_FALSE(context.IsValidRange(
33         ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
34     EXPECT_FALSE(context.ClaimMemory(
35         ToPtr(std::numeric_limits<uintptr_t>::max() - 3000), 1));
36   }
37 
38   if (sizeof(size_t) > sizeof(uint32_t)) {
39     // Test handle index range overflow.
40     size_t num_handles =
41         static_cast<size_t>(std::numeric_limits<uint32_t>::max()) + 5;
42     internal::ValidationContext context(ToPtr(0), 0, num_handles);
43 
44     EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
45     EXPECT_FALSE(context.ClaimHandle(
46         Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
47 
48     EXPECT_TRUE(context.ClaimHandle(
49         Handle_Data(internal::kEncodedInvalidHandleValue)));
50   }
51 }
52 #endif
53 
TEST(ValidationContextTest,IsValidRange)54 TEST(ValidationContextTest, IsValidRange) {
55   {
56     internal::ValidationContext context(ToPtr(1234), 100, 0);
57 
58     // Basics.
59     EXPECT_FALSE(context.IsValidRange(ToPtr(100), 5));
60     EXPECT_FALSE(context.IsValidRange(ToPtr(1230), 50));
61     EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 5));
62     EXPECT_TRUE(context.IsValidRange(ToPtr(1240), 50));
63     EXPECT_TRUE(context.IsValidRange(ToPtr(1234), 100));
64     EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 101));
65     EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 100));
66     EXPECT_FALSE(context.IsValidRange(ToPtr(1333), 5));
67     EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 5));
68 
69     // ClaimMemory() updates the valid range.
70     EXPECT_TRUE(context.ClaimMemory(ToPtr(1254), 10));
71 
72     EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
73     EXPECT_FALSE(context.IsValidRange(ToPtr(1254), 10));
74     EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 1));
75     EXPECT_FALSE(context.IsValidRange(ToPtr(1263), 10));
76     EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 10));
77     EXPECT_TRUE(context.IsValidRange(ToPtr(1264), 70));
78     EXPECT_FALSE(context.IsValidRange(ToPtr(1264), 71));
79   }
80 
81   {
82     internal::ValidationContext context(ToPtr(1234), 100, 0);
83     // Should return false for empty ranges.
84     EXPECT_FALSE(context.IsValidRange(ToPtr(0), 0));
85     EXPECT_FALSE(context.IsValidRange(ToPtr(1200), 0));
86     EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
87     EXPECT_FALSE(context.IsValidRange(ToPtr(1240), 0));
88     EXPECT_FALSE(context.IsValidRange(ToPtr(2234), 0));
89   }
90 
91   {
92     // The valid memory range is empty.
93     internal::ValidationContext context(ToPtr(1234), 0, 0);
94 
95     EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 1));
96     EXPECT_FALSE(context.IsValidRange(ToPtr(1234), 0));
97   }
98 
99   {
100     internal::ValidationContext context(
101         ToPtr(std::numeric_limits<uintptr_t>::max() - 2000), 1000, 0);
102 
103     // Test overflow.
104     EXPECT_FALSE(context.IsValidRange(
105         ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 4000));
106     EXPECT_FALSE(context.IsValidRange(
107         ToPtr(std::numeric_limits<uintptr_t>::max() - 1500),
108         std::numeric_limits<uint32_t>::max()));
109 
110     // This should be fine.
111     EXPECT_TRUE(context.IsValidRange(
112         ToPtr(std::numeric_limits<uintptr_t>::max() - 1500), 200));
113   }
114 }
115 
TEST(ValidationContextTest,ClaimHandle)116 TEST(ValidationContextTest, ClaimHandle) {
117   {
118     internal::ValidationContext context(ToPtr(0), 0, 10);
119 
120     // Basics.
121     EXPECT_TRUE(context.ClaimHandle(Handle_Data(0)));
122     EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
123 
124     EXPECT_TRUE(context.ClaimHandle(Handle_Data(9)));
125     EXPECT_FALSE(context.ClaimHandle(Handle_Data(10)));
126 
127     // Should fail because it is smaller than the max index that has been
128     // claimed.
129     EXPECT_FALSE(context.ClaimHandle(Handle_Data(8)));
130 
131     // Should return true for invalid handle.
132     EXPECT_TRUE(context.ClaimHandle(
133         Handle_Data(internal::kEncodedInvalidHandleValue)));
134     EXPECT_TRUE(context.ClaimHandle(
135         Handle_Data(internal::kEncodedInvalidHandleValue)));
136   }
137 
138   {
139     // No handle to claim.
140     internal::ValidationContext context(ToPtr(0), 0, 0);
141 
142     EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
143 
144     // Should still return true for invalid handle.
145     EXPECT_TRUE(context.ClaimHandle(
146         Handle_Data(internal::kEncodedInvalidHandleValue)));
147   }
148 
149   {
150     // Test the case that |num_handles| is the same value as
151     // |internal::kEncodedInvalidHandleValue|.
152     EXPECT_EQ(internal::kEncodedInvalidHandleValue,
153               std::numeric_limits<uint32_t>::max());
154     internal::ValidationContext context(
155         ToPtr(0), 0, std::numeric_limits<uint32_t>::max());
156 
157     EXPECT_TRUE(context.ClaimHandle(
158         Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
159     EXPECT_FALSE(context.ClaimHandle(
160         Handle_Data(std::numeric_limits<uint32_t>::max() - 1)));
161     EXPECT_FALSE(context.ClaimHandle(Handle_Data(0)));
162 
163     // Should still return true for invalid handle.
164     EXPECT_TRUE(context.ClaimHandle(
165         Handle_Data(internal::kEncodedInvalidHandleValue)));
166   }
167 }
168 
TEST(ValidationContextTest,ClaimMemory)169 TEST(ValidationContextTest, ClaimMemory) {
170   {
171     internal::ValidationContext context(ToPtr(1000), 2000, 0);
172 
173     // Basics.
174     EXPECT_FALSE(context.ClaimMemory(ToPtr(500), 100));
175     EXPECT_FALSE(context.ClaimMemory(ToPtr(800), 300));
176     EXPECT_TRUE(context.ClaimMemory(ToPtr(1000), 100));
177     EXPECT_FALSE(context.ClaimMemory(ToPtr(1099), 100));
178     EXPECT_TRUE(context.ClaimMemory(ToPtr(1100), 200));
179     EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 1001));
180     EXPECT_TRUE(context.ClaimMemory(ToPtr(2000), 500));
181     EXPECT_FALSE(context.ClaimMemory(ToPtr(2000), 500));
182     EXPECT_FALSE(context.ClaimMemory(ToPtr(1400), 100));
183     EXPECT_FALSE(context.ClaimMemory(ToPtr(3000), 1));
184     EXPECT_TRUE(context.ClaimMemory(ToPtr(2500), 500));
185   }
186 
187   {
188     // No memory to claim.
189     internal::ValidationContext context(ToPtr(10000), 0, 0);
190 
191     EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 1));
192     EXPECT_FALSE(context.ClaimMemory(ToPtr(10000), 0));
193   }
194 
195   {
196     internal::ValidationContext context(
197         ToPtr(std::numeric_limits<uintptr_t>::max() - 1000), 500, 0);
198 
199     // Test overflow.
200     EXPECT_FALSE(context.ClaimMemory(
201         ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 4000));
202     EXPECT_FALSE(
203         context.ClaimMemory(ToPtr(std::numeric_limits<uintptr_t>::max() - 750),
204                             std::numeric_limits<uint32_t>::max()));
205 
206     // This should be fine.
207     EXPECT_TRUE(context.ClaimMemory(
208         ToPtr(std::numeric_limits<uintptr_t>::max() - 750), 200));
209   }
210 }
211 
212 }  // namespace
213 }  // namespace test
214 }  // namespace mojo
215