1 // Copyright 2013 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 <gtest/gtest.h> 6 7 #include <sstream> 8 #include <vector> 9 10 #include "base/safe_numerics.h" 11 12 namespace base { 13 namespace internal { 14 15 // This is far (far, far) too slow to run normally, but if you're refactoring 16 // it might be useful. 17 // #define RUN_EXHAUSTIVE_TEST 18 19 #ifdef RUN_EXHAUSTIVE_TEST 20 21 template <class From, class To> void ExhaustiveCheckFromTo() { 22 fprintf(stderr, "."); 23 From i = std::numeric_limits<From>::min(); 24 for (;;) { 25 std::ostringstream str_from, str_to; 26 str_from << i; 27 To to = static_cast<To>(i); 28 str_to << to; 29 bool strings_equal = str_from.str() == str_to.str(); 30 EXPECT_EQ(IsValidNumericCast<To>(i), strings_equal); 31 fprintf(stderr, "\r%s vs %s\x1B[K", 32 str_from.str().c_str(), str_to.str().c_str()); 33 ++i; 34 // If we wrap, then we've tested everything. 35 if (i == std::numeric_limits<From>::min()) 36 break; 37 } 38 } 39 40 template <class From> void ExhaustiveCheckFrom() { 41 ExhaustiveCheckFromTo<From, short>(); 42 ExhaustiveCheckFromTo<From, unsigned short>(); 43 ExhaustiveCheckFromTo<From, int>(); 44 ExhaustiveCheckFromTo<From, unsigned int>(); 45 ExhaustiveCheckFromTo<From, long long>(); 46 ExhaustiveCheckFromTo<From, unsigned long long>(); 47 ExhaustiveCheckFromTo<From, size_t>(); 48 fprintf(stderr, "\n"); 49 } 50 51 #endif 52 53 54 TEST(SafeNumerics, NumericCast) { 55 int small_positive = 1; 56 int small_negative = -1; 57 int large_positive = INT_MAX; 58 int large_negative = INT_MIN; 59 size_t size_t_small = 1; 60 size_t size_t_large = UINT_MAX; 61 62 // Narrow signed destination. 63 EXPECT_TRUE(IsValidNumericCast<signed char>(small_positive)); 64 EXPECT_TRUE(IsValidNumericCast<signed char>(small_negative)); 65 EXPECT_FALSE(IsValidNumericCast<signed char>(large_positive)); 66 EXPECT_FALSE(IsValidNumericCast<signed char>(large_negative)); 67 EXPECT_TRUE(IsValidNumericCast<signed short>(small_positive)); 68 EXPECT_TRUE(IsValidNumericCast<signed short>(small_negative)); 69 70 // Narrow unsigned destination. 71 EXPECT_TRUE(IsValidNumericCast<unsigned char>(small_positive)); 72 EXPECT_FALSE(IsValidNumericCast<unsigned char>(small_negative)); 73 EXPECT_FALSE(IsValidNumericCast<unsigned char>(large_positive)); 74 EXPECT_FALSE(IsValidNumericCast<unsigned char>(large_negative)); 75 EXPECT_FALSE(IsValidNumericCast<unsigned short>(small_negative)); 76 EXPECT_FALSE(IsValidNumericCast<unsigned short>(large_negative)); 77 78 // Same width signed destination. 79 EXPECT_TRUE(IsValidNumericCast<signed int>(small_positive)); 80 EXPECT_TRUE(IsValidNumericCast<signed int>(small_negative)); 81 EXPECT_TRUE(IsValidNumericCast<signed int>(large_positive)); 82 EXPECT_TRUE(IsValidNumericCast<signed int>(large_negative)); 83 84 // Same width unsigned destination. 85 EXPECT_TRUE(IsValidNumericCast<unsigned int>(small_positive)); 86 EXPECT_FALSE(IsValidNumericCast<unsigned int>(small_negative)); 87 EXPECT_TRUE(IsValidNumericCast<unsigned int>(large_positive)); 88 EXPECT_FALSE(IsValidNumericCast<unsigned int>(large_negative)); 89 90 // Wider signed destination. 91 EXPECT_TRUE(IsValidNumericCast<long long>(small_positive)); 92 EXPECT_TRUE(IsValidNumericCast<long long>(large_negative)); 93 EXPECT_TRUE(IsValidNumericCast<long long>(small_positive)); 94 EXPECT_TRUE(IsValidNumericCast<long long>(large_negative)); 95 96 // Wider unsigned destination. 97 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(small_positive)); 98 EXPECT_FALSE(IsValidNumericCast<unsigned long long>(small_negative)); 99 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(large_positive)); 100 EXPECT_FALSE(IsValidNumericCast<unsigned long long>(large_negative)); 101 102 // Negative to size_t. 103 EXPECT_FALSE(IsValidNumericCast<size_t>(small_negative)); 104 EXPECT_FALSE(IsValidNumericCast<size_t>(large_negative)); 105 106 // From unsigned. 107 // Small. 108 EXPECT_TRUE(IsValidNumericCast<signed char>(size_t_small)); 109 EXPECT_TRUE(IsValidNumericCast<unsigned char>(size_t_small)); 110 EXPECT_TRUE(IsValidNumericCast<short>(size_t_small)); 111 EXPECT_TRUE(IsValidNumericCast<unsigned short>(size_t_small)); 112 EXPECT_TRUE(IsValidNumericCast<int>(size_t_small)); 113 EXPECT_TRUE(IsValidNumericCast<unsigned int>(size_t_small)); 114 EXPECT_TRUE(IsValidNumericCast<long long>(size_t_small)); 115 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(size_t_small)); 116 117 // Large. 118 EXPECT_FALSE(IsValidNumericCast<signed char>(size_t_large)); 119 EXPECT_FALSE(IsValidNumericCast<unsigned char>(size_t_large)); 120 EXPECT_FALSE(IsValidNumericCast<short>(size_t_large)); 121 EXPECT_FALSE(IsValidNumericCast<unsigned short>(size_t_large)); 122 EXPECT_FALSE(IsValidNumericCast<int>(size_t_large)); 123 EXPECT_TRUE(IsValidNumericCast<unsigned int>(size_t_large)); 124 EXPECT_TRUE(IsValidNumericCast<long long>(size_t_large)); 125 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(size_t_large)); 126 127 // Various edge cases. 128 EXPECT_TRUE(IsValidNumericCast<int>(static_cast<short>(SHRT_MIN))); 129 EXPECT_FALSE( 130 IsValidNumericCast<unsigned short>(static_cast<short>(SHRT_MIN))); 131 EXPECT_FALSE(IsValidNumericCast<unsigned short>(SHRT_MIN)); 132 133 // Confirm that checked_numeric_cast<> actually compiles. 134 std::vector<int> v; 135 unsigned int checked_size = 136 base::checked_numeric_cast<unsigned int>(v.size()); 137 EXPECT_EQ(0u, checked_size); 138 139 #ifdef RUN_EXHAUSTIVE_TEST 140 ExhaustiveCheckFrom<short>(); 141 ExhaustiveCheckFrom<unsigned short>(); 142 ExhaustiveCheckFrom<int>(); 143 ExhaustiveCheckFrom<unsigned int>(); 144 ExhaustiveCheckFrom<long long>(); 145 ExhaustiveCheckFrom<unsigned long long>(); 146 ExhaustiveCheckFrom<size_t>(); 147 #endif 148 } 149 150 } // namespace internal 151 } // namespace base 152