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 <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