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