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