Home | History | Annotate | Download | only in tests
      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