1 // Copyright 2022 The Chromium Authors
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 "base/strings/abseil_string_number_conversions.h"
6
7 #include <stdint.h>
8
9 #include <limits>
10
11 #include "base/strings/string_piece.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/abseil-cpp/absl/numeric/int128.h"
14
15 namespace base {
16
TEST(AbseilStringNumberConversionsTest,StringToUint128)17 TEST(AbseilStringNumberConversionsTest, StringToUint128) {
18 // Test cases adapted from `StringNumberConversionsTest.StringToUint64`.
19 static const struct {
20 std::string input;
21 absl::uint128 output;
22 bool success;
23 } cases[] = {
24 {"0", 0, true},
25 {"42", 42, true},
26 {"-2147483648", 0, false},
27 {"2147483647", INT_MAX, true},
28 {"-2147483649", 0, false},
29 {"-99999999999", 0, false},
30 {"2147483648", UINT64_C(2147483648), true},
31 {"99999999999", UINT64_C(99999999999), true},
32 {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
33 {"-9223372036854775808", 0, false},
34 {"09", 9, true},
35 {"-09", 0, false},
36 {"", 0, false},
37 {" 42", 42, false},
38 {"42 ", 42, false},
39 {"0x42", 0, false},
40 {"\t\n\v\f\r 42", 42, false},
41 {"blah42", 0, false},
42 {"42blah", 42, false},
43 {"blah42blah", 0, false},
44 {"-273.15", 0, false},
45 {"+98.6", 98, false},
46 {"--123", 0, false},
47 {"++123", 0, false},
48 {"-+123", 0, false},
49 {"+-123", 0, false},
50 {"-", 0, false},
51 {"-9223372036854775809", 0, false},
52 {"-99999999999999999999", 0, false},
53 {"9223372036854775808", UINT64_C(9223372036854775808), true},
54 {"99999999999999999999",
55 absl::MakeUint128(/*high=*/5, /*low=*/UINT64_C(7766279631452241919)),
56 true},
57 {"18446744073709551615", std::numeric_limits<uint64_t>::max(), true},
58 {"18446744073709551616", absl::MakeUint128(/*high=*/1, /*low=*/0), true},
59 {"123456789012345678901234567890123456789",
60 absl::MakeUint128(/*high=*/UINT64_C(6692605942763486917),
61 /*low=*/UINT64_C(12312739301371248917)),
62 true},
63 {"-170141183460469231731687303715884105728", 0, false},
64 {"-170141183460469231731687303715884105729", 0, false},
65 {"-999999999999999999999999999999999999999", 0, false},
66 {"170141183460469231731687303715884105727",
67 std::numeric_limits<absl::int128>::max(), true},
68 {"340282366920938463463374607431768211455",
69 std::numeric_limits<absl::uint128>::max(), true},
70 {"340282366920938463463374607431768211456",
71 std::numeric_limits<absl::uint128>::max(), false},
72 {"999999999999999999999999999999999999999",
73 std::numeric_limits<absl::uint128>::max(), false},
74 };
75
76 for (const auto& i : cases) {
77 absl::uint128 output = 0;
78 EXPECT_EQ(i.success, StringToUint128(i.input, &output)) << i.input;
79 EXPECT_EQ(i.output, output);
80 }
81
82 // One additional test to verify that conversion of numbers in strings with
83 // embedded NUL characters. The NUL and extra data after it should be
84 // interpreted as junk after the number.
85 const char input[] =
86 "6\0"
87 "6";
88 std::string input_string(input, std::size(input) - 1);
89 absl::uint128 output;
90 EXPECT_FALSE(StringToUint128(input_string, &output));
91 EXPECT_EQ(6U, output);
92 }
93
TEST(AbseilStringNumberConversionsTest,HexStringToUInt128)94 TEST(AbseilStringNumberConversionsTest, HexStringToUInt128) {
95 // Test cases adapted from `StringNumberConversionsTest.HexStringToUint64`.
96 static const struct {
97 std::string input;
98 absl::uint128 output;
99 bool success;
100 } cases[] = {
101 {"0", 0, true},
102 {"42", 66, true},
103 {"-42", 0, false},
104 {"+42", 66, true},
105 {"ffffffffffffffff",
106 absl::MakeUint128(/*high=*/0,
107 /*low=*/std::numeric_limits<uint64_t>::max()),
108 true},
109 {"1ffffffffffffffff",
110 absl::MakeUint128(/*high=*/1,
111 /*low=*/std::numeric_limits<uint64_t>::max()),
112 true},
113 {"7fffffff", INT_MAX, true},
114 {"-80000000", 0, false},
115 {"ffffffff", 0xffffffff, true},
116 {"DeadBeef", 0xdeadbeef, true},
117 {"0x42", 66, true},
118 {"-0x42", 0, false},
119 {"+0x42", 66, true},
120 {"0xffffffffffffffff",
121 absl::MakeUint128(/*high=*/0,
122 /*low=*/std::numeric_limits<uint64_t>::max()),
123 true},
124 {"0x1ffffffffffffffff",
125 absl::MakeUint128(/*high=*/1,
126 /*low=*/std::numeric_limits<uint64_t>::max()),
127 true},
128 {"0x7fffffff", INT_MAX, true},
129 {"-0x80000000", 0, false},
130 {"0xffffffff", 0xffffffff, true},
131 {"0XDeadBeef", 0xdeadbeef, true},
132 {"0x7fffffffffffffffffffffffffffffff",
133 std::numeric_limits<absl::int128>::max(), true},
134 {"-0x8000000000000000", 0, false},
135 {"0x8000000000000000",
136 absl::MakeUint128(/*high=*/0, UINT64_C(0x8000000000000000)), true},
137 {"-0x8000000000000001", 0, false},
138 {"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
139 std::numeric_limits<absl::uint128>::max(), true},
140 {"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
141 std::numeric_limits<absl::uint128>::max(), true},
142 {"0x0000000000000000", 0, true},
143 {"0000000000000000", 0, true},
144 {"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
145 std::numeric_limits<absl::uint128>::max(), false}, // Overflow test.
146 {"0x0f", 15, true},
147 {"0f", 15, true},
148 {" 45", 0x45, false},
149 {"\t\n\v\f\r 0x45", 0x45, false},
150 {" 45", 0x45, false},
151 {"45 ", 0x45, false},
152 {"45:", 0x45, false},
153 {"efgh", 0xef, false},
154 {"0xefgh", 0xef, false},
155 {"hgfe", 0, false},
156 {"-", 0, false},
157 {"", 0, false},
158 {"0x", 0, false},
159 };
160
161 for (const auto& i : cases) {
162 absl::uint128 output = 0;
163 EXPECT_EQ(i.success, HexStringToUInt128(i.input, &output)) << i.input;
164 EXPECT_EQ(i.output, output) << i.input;
165 }
166 // One additional test to verify that conversion of numbers in strings with
167 // embedded NUL characters. The NUL and extra data after it should be
168 // interpreted as junk after the number.
169 const char input[] =
170 "0xc0ffee\0"
171 "9";
172 std::string input_string(input, std::size(input) - 1);
173 absl::uint128 output;
174 EXPECT_FALSE(HexStringToUInt128(input_string, &output));
175 EXPECT_EQ(0xc0ffeeU, output);
176 }
177
178 } // namespace base
179