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 21 const void* ToPtr(uintptr_t ptr) { 22 return reinterpret_cast<const void*>(ptr); 23 } 24 25 #if defined(NDEBUG) && !defined(DCHECK_ALWAYS_ON) 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 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 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 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