Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1928)

Side by Side Diff: base/safe_numerics_unittest.cc

Issue 131063002: Expand support in safe_numeric.h (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Removed macros and split out implementation header Created 6 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <gtest/gtest.h> 5 #include <gtest/gtest.h>
6 6
7 #include <stdint.h>
akalin 2014/01/14 00:49:19 why mix c-style and c++-style libc headers? I'd go
jschuh 2014/01/14 05:24:33 Done.
8
9 #include <cmath>
7 #include <sstream> 10 #include <sstream>
8 #include <vector> 11 #include <vector>
9 12
10 #include "base/safe_numerics.h" 13 #include "base/safe_numerics.h"
11 14
12 namespace base { 15 namespace base {
13 namespace internal { 16 namespace internal {
14 17
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) { 18 TEST(SafeNumerics, NumericCast) {
55 int small_positive = 1; 19 int small_positive = 1;
56 int small_negative = -1; 20 int small_negative = -1;
57 int large_positive = INT_MAX; 21 int large_positive = INT_MAX;
58 int large_negative = INT_MIN; 22 int large_negative = INT_MIN;
59 size_t size_t_small = 1; 23 size_t size_t_small = 1;
60 size_t size_t_large = UINT_MAX; 24 size_t size_t_large = UINT_MAX;
25 double double_small = 1.0;
26 double double_large = DBL_MAX;
27 double double_negative = -1.0;
28 double double_nan = std::numeric_limits<double>::quiet_NaN();
29 double double_infinity = std::numeric_limits<double>::infinity();
61 30
62 // Narrow signed destination. 31 // Narrow signed destination.
63 EXPECT_TRUE(IsValidNumericCast<signed char>(small_positive)); 32 EXPECT_EQ(NumericRangeCheck<signed char>(small_positive), TYPE_VALID);
64 EXPECT_TRUE(IsValidNumericCast<signed char>(small_negative)); 33 EXPECT_EQ(NumericRangeCheck<signed char>(small_negative), TYPE_VALID);
65 EXPECT_FALSE(IsValidNumericCast<signed char>(large_positive)); 34 EXPECT_EQ(NumericRangeCheck<signed char>(large_positive), TYPE_OVERFLOW);
66 EXPECT_FALSE(IsValidNumericCast<signed char>(large_negative)); 35 EXPECT_EQ(NumericRangeCheck<signed char>(large_negative), TYPE_UNDERFLOW);
67 EXPECT_TRUE(IsValidNumericCast<signed short>(small_positive)); 36 EXPECT_EQ(NumericRangeCheck<int16_t>(small_positive), TYPE_VALID);
68 EXPECT_TRUE(IsValidNumericCast<signed short>(small_negative)); 37 EXPECT_EQ(NumericRangeCheck<int16_t>(small_negative), TYPE_VALID);
69 38
70 // Narrow unsigned destination. 39 // Narrow unsigned destination.
71 EXPECT_TRUE(IsValidNumericCast<unsigned char>(small_positive)); 40 EXPECT_EQ(NumericRangeCheck<unsigned char>(small_positive), TYPE_VALID);
72 EXPECT_FALSE(IsValidNumericCast<unsigned char>(small_negative)); 41 EXPECT_EQ(NumericRangeCheck<unsigned char>(small_negative), TYPE_UNDERFLOW);
73 EXPECT_FALSE(IsValidNumericCast<unsigned char>(large_positive)); 42 EXPECT_EQ(NumericRangeCheck<unsigned char>(large_positive), TYPE_OVERFLOW);
74 EXPECT_FALSE(IsValidNumericCast<unsigned char>(large_negative)); 43 EXPECT_EQ(NumericRangeCheck<unsigned char>(large_negative), TYPE_UNDERFLOW);
75 EXPECT_FALSE(IsValidNumericCast<unsigned short>(small_negative)); 44 EXPECT_EQ(NumericRangeCheck<uint16_t>(small_negative), TYPE_UNDERFLOW);
76 EXPECT_FALSE(IsValidNumericCast<unsigned short>(large_negative)); 45 EXPECT_EQ(NumericRangeCheck<uint16_t>(large_negative), TYPE_UNDERFLOW);
77 46
78 // Same width signed destination. 47 // Same width signed destination.
79 EXPECT_TRUE(IsValidNumericCast<signed int>(small_positive)); 48 EXPECT_EQ(NumericRangeCheck<signed int>(small_positive), TYPE_VALID);
80 EXPECT_TRUE(IsValidNumericCast<signed int>(small_negative)); 49 EXPECT_EQ(NumericRangeCheck<signed int>(small_negative), TYPE_VALID);
81 EXPECT_TRUE(IsValidNumericCast<signed int>(large_positive)); 50 EXPECT_EQ(NumericRangeCheck<signed int>(large_positive), TYPE_VALID);
82 EXPECT_TRUE(IsValidNumericCast<signed int>(large_negative)); 51 EXPECT_EQ(NumericRangeCheck<signed int>(large_negative), TYPE_VALID);
83 52
84 // Same width unsigned destination. 53 // Same width unsigned destination.
85 EXPECT_TRUE(IsValidNumericCast<unsigned int>(small_positive)); 54 EXPECT_EQ(NumericRangeCheck<unsigned int>(small_positive), TYPE_VALID);
86 EXPECT_FALSE(IsValidNumericCast<unsigned int>(small_negative)); 55 EXPECT_EQ(NumericRangeCheck<unsigned int>(small_negative), TYPE_UNDERFLOW);
87 EXPECT_TRUE(IsValidNumericCast<unsigned int>(large_positive)); 56 EXPECT_EQ(NumericRangeCheck<unsigned int>(large_positive), TYPE_VALID);
88 EXPECT_FALSE(IsValidNumericCast<unsigned int>(large_negative)); 57 EXPECT_EQ(NumericRangeCheck<unsigned int>(large_negative), TYPE_UNDERFLOW);
89 58
90 // Wider signed destination. 59 // Wider signed destination.
91 EXPECT_TRUE(IsValidNumericCast<long long>(small_positive)); 60 EXPECT_EQ(NumericRangeCheck<int64_t>(small_positive), TYPE_VALID);
92 EXPECT_TRUE(IsValidNumericCast<long long>(large_negative)); 61 EXPECT_EQ(NumericRangeCheck<int64_t>(large_negative), TYPE_VALID);
93 EXPECT_TRUE(IsValidNumericCast<long long>(small_positive)); 62 EXPECT_EQ(NumericRangeCheck<int64_t>(small_positive), TYPE_VALID);
94 EXPECT_TRUE(IsValidNumericCast<long long>(large_negative)); 63 EXPECT_EQ(NumericRangeCheck<int64_t>(large_negative), TYPE_VALID);
95 64
96 // Wider unsigned destination. 65 // Wider unsigned destination.
97 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(small_positive)); 66 EXPECT_EQ(NumericRangeCheck<uint64_t>(small_positive), TYPE_VALID);
98 EXPECT_FALSE(IsValidNumericCast<unsigned long long>(small_negative)); 67 EXPECT_EQ(NumericRangeCheck<uint64_t>(small_negative),
99 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(large_positive)); 68 TYPE_UNDERFLOW);
100 EXPECT_FALSE(IsValidNumericCast<unsigned long long>(large_negative)); 69 EXPECT_EQ(NumericRangeCheck<uint64_t>(large_positive), TYPE_VALID);
70 EXPECT_EQ(NumericRangeCheck<uint64_t>(large_negative),
71 TYPE_UNDERFLOW);
101 72
102 // Negative to size_t. 73 // Negative to size_t.
103 EXPECT_FALSE(IsValidNumericCast<size_t>(small_negative)); 74 EXPECT_EQ(NumericRangeCheck<size_t>(small_negative), TYPE_UNDERFLOW);
104 EXPECT_FALSE(IsValidNumericCast<size_t>(large_negative)); 75 EXPECT_EQ(NumericRangeCheck<size_t>(large_negative), TYPE_UNDERFLOW);
76
77 // Floating point conversions.
78 EXPECT_EQ(NumericRangeCheck<int>(double_small), TYPE_VALID);
79 EXPECT_EQ(NumericRangeCheck<int>(double_large), TYPE_OVERFLOW);
80 EXPECT_EQ(NumericRangeCheck<int>(double_negative), TYPE_VALID);
81 EXPECT_EQ(NumericRangeCheck<unsigned int>(double_negative), TYPE_UNDERFLOW);
82 EXPECT_EQ(NumericRangeCheck<int>(double_infinity), TYPE_OVERFLOW);
83 EXPECT_EQ(NumericRangeCheck<int>(-double_infinity), TYPE_UNDERFLOW);
84 EXPECT_EQ(NumericRangeCheck<unsigned int>(double_infinity), TYPE_OVERFLOW);
85 EXPECT_EQ(NumericRangeCheck<unsigned int>(-double_infinity), TYPE_UNDERFLOW);
86 EXPECT_EQ(NumericRangeCheck<unsigned int>(double_nan), TYPE_INVALID);
105 87
106 // From unsigned. 88 // From unsigned.
107 // Small. 89 // Small.
108 EXPECT_TRUE(IsValidNumericCast<signed char>(size_t_small)); 90 EXPECT_EQ(NumericRangeCheck<signed char>(size_t_small), TYPE_VALID);
109 EXPECT_TRUE(IsValidNumericCast<unsigned char>(size_t_small)); 91 EXPECT_EQ(NumericRangeCheck<unsigned char>(size_t_small), TYPE_VALID);
110 EXPECT_TRUE(IsValidNumericCast<short>(size_t_small)); 92 EXPECT_EQ(NumericRangeCheck<int16_t>(size_t_small), TYPE_VALID);
111 EXPECT_TRUE(IsValidNumericCast<unsigned short>(size_t_small)); 93 EXPECT_EQ(NumericRangeCheck<uint16_t>(size_t_small), TYPE_VALID);
112 EXPECT_TRUE(IsValidNumericCast<int>(size_t_small)); 94 EXPECT_EQ(NumericRangeCheck<int>(size_t_small), TYPE_VALID);
113 EXPECT_TRUE(IsValidNumericCast<unsigned int>(size_t_small)); 95 EXPECT_EQ(NumericRangeCheck<unsigned int>(size_t_small), TYPE_VALID);
114 EXPECT_TRUE(IsValidNumericCast<long long>(size_t_small)); 96 EXPECT_EQ(NumericRangeCheck<int64_t>(size_t_small), TYPE_VALID);
115 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(size_t_small)); 97 EXPECT_EQ(NumericRangeCheck<uint64_t>(size_t_small), TYPE_VALID);
116 98
117 // Large. 99 // Large.
118 EXPECT_FALSE(IsValidNumericCast<signed char>(size_t_large)); 100 EXPECT_EQ(NumericRangeCheck<signed char>(size_t_large), TYPE_OVERFLOW);
119 EXPECT_FALSE(IsValidNumericCast<unsigned char>(size_t_large)); 101 EXPECT_EQ(NumericRangeCheck<unsigned char>(size_t_large), TYPE_OVERFLOW);
120 EXPECT_FALSE(IsValidNumericCast<short>(size_t_large)); 102 EXPECT_EQ(NumericRangeCheck<int16_t>(size_t_large), TYPE_OVERFLOW);
121 EXPECT_FALSE(IsValidNumericCast<unsigned short>(size_t_large)); 103 EXPECT_EQ(NumericRangeCheck<uint16_t>(size_t_large), TYPE_OVERFLOW);
122 EXPECT_FALSE(IsValidNumericCast<int>(size_t_large)); 104 EXPECT_EQ(NumericRangeCheck<int>(size_t_large), TYPE_OVERFLOW);
123 EXPECT_TRUE(IsValidNumericCast<unsigned int>(size_t_large)); 105 EXPECT_EQ(NumericRangeCheck<unsigned int>(size_t_large), TYPE_VALID);
124 EXPECT_TRUE(IsValidNumericCast<long long>(size_t_large)); 106 EXPECT_EQ(NumericRangeCheck<int64_t>(size_t_large), TYPE_VALID);
125 EXPECT_TRUE(IsValidNumericCast<unsigned long long>(size_t_large)); 107 EXPECT_EQ(NumericRangeCheck<uint64_t>(size_t_large), TYPE_VALID);
126 108
127 // Various edge cases. 109 // Various edge cases.
128 EXPECT_TRUE(IsValidNumericCast<int>(static_cast<short>(SHRT_MIN))); 110 EXPECT_EQ(NumericRangeCheck<int>(static_cast<int16_t>(SHRT_MIN)), TYPE_VALID);
129 EXPECT_FALSE( 111 EXPECT_EQ(NumericRangeCheck<uint16_t>(static_cast<int16_t>(SHRT_MIN)),
130 IsValidNumericCast<unsigned short>(static_cast<short>(SHRT_MIN))); 112 TYPE_UNDERFLOW);
131 EXPECT_FALSE(IsValidNumericCast<unsigned short>(SHRT_MIN)); 113 EXPECT_EQ(NumericRangeCheck<uint16_t>(SHRT_MIN), TYPE_UNDERFLOW);
114
115 // Basic saturation tests.
116 EXPECT_EQ(saturated_cast<int>(small_negative),
117 static_cast<int>(small_negative));
118 EXPECT_EQ(saturated_cast<int>(small_positive),
akalin 2014/01/14 00:49:19 this repeats previous test. did you mean large_pos
jschuh 2014/01/14 05:24:33 Which does it repeat?
119 static_cast<int>(small_positive));
120 EXPECT_EQ(saturated_cast<unsigned>(small_negative),
121 static_cast<unsigned>(0));
122 EXPECT_EQ(saturated_cast<int>(double_small),
123 static_cast<int>(double_small));
124 EXPECT_EQ(saturated_cast<int>(double_large),
125 std::numeric_limits<int>::max());
132 126
133 // Confirm that checked_numeric_cast<> actually compiles. 127 // Confirm that checked_numeric_cast<> actually compiles.
134 std::vector<int> v; 128 std::vector<int> v;
135 unsigned int checked_size = 129 unsigned int checked_size =
136 base::checked_numeric_cast<unsigned int>(v.size()); 130 base::checked_numeric_cast<unsigned int>(v.size());
137 EXPECT_EQ(0u, checked_size); 131 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 } 132 }
149 133
150 } // namespace internal 134 } // namespace internal
151 } // namespace base 135 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698