179 lines
6.2 KiB
C++
179 lines
6.2 KiB
C++
// Copyright 2022 The Chromium Authors
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "base/strings/abseil_string_number_conversions.h"
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <limits>
|
|
|
|
#include "base/strings/string_piece.h"
|
|
#include "testing/gtest/include/gtest/gtest.h"
|
|
#include "third_party/abseil-cpp/absl/numeric/int128.h"
|
|
|
|
namespace base {
|
|
|
|
TEST(AbseilStringNumberConversionsTest, StringToUint128) {
|
|
// Test cases adapted from `StringNumberConversionsTest.StringToUint64`.
|
|
static const struct {
|
|
std::string input;
|
|
absl::uint128 output;
|
|
bool success;
|
|
} cases[] = {
|
|
{"0", 0, true},
|
|
{"42", 42, true},
|
|
{"-2147483648", 0, false},
|
|
{"2147483647", INT_MAX, true},
|
|
{"-2147483649", 0, false},
|
|
{"-99999999999", 0, false},
|
|
{"2147483648", UINT64_C(2147483648), true},
|
|
{"99999999999", UINT64_C(99999999999), true},
|
|
{"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
|
|
{"-9223372036854775808", 0, false},
|
|
{"09", 9, true},
|
|
{"-09", 0, false},
|
|
{"", 0, false},
|
|
{" 42", 42, false},
|
|
{"42 ", 42, false},
|
|
{"0x42", 0, false},
|
|
{"\t\n\v\f\r 42", 42, false},
|
|
{"blah42", 0, false},
|
|
{"42blah", 42, false},
|
|
{"blah42blah", 0, false},
|
|
{"-273.15", 0, false},
|
|
{"+98.6", 98, false},
|
|
{"--123", 0, false},
|
|
{"++123", 0, false},
|
|
{"-+123", 0, false},
|
|
{"+-123", 0, false},
|
|
{"-", 0, false},
|
|
{"-9223372036854775809", 0, false},
|
|
{"-99999999999999999999", 0, false},
|
|
{"9223372036854775808", UINT64_C(9223372036854775808), true},
|
|
{"99999999999999999999",
|
|
absl::MakeUint128(/*high=*/5, /*low=*/UINT64_C(7766279631452241919)),
|
|
true},
|
|
{"18446744073709551615", std::numeric_limits<uint64_t>::max(), true},
|
|
{"18446744073709551616", absl::MakeUint128(/*high=*/1, /*low=*/0), true},
|
|
{"123456789012345678901234567890123456789",
|
|
absl::MakeUint128(/*high=*/UINT64_C(6692605942763486917),
|
|
/*low=*/UINT64_C(12312739301371248917)),
|
|
true},
|
|
{"-170141183460469231731687303715884105728", 0, false},
|
|
{"-170141183460469231731687303715884105729", 0, false},
|
|
{"-999999999999999999999999999999999999999", 0, false},
|
|
{"170141183460469231731687303715884105727",
|
|
std::numeric_limits<absl::int128>::max(), true},
|
|
{"340282366920938463463374607431768211455",
|
|
std::numeric_limits<absl::uint128>::max(), true},
|
|
{"340282366920938463463374607431768211456",
|
|
std::numeric_limits<absl::uint128>::max(), false},
|
|
{"999999999999999999999999999999999999999",
|
|
std::numeric_limits<absl::uint128>::max(), false},
|
|
};
|
|
|
|
for (const auto& i : cases) {
|
|
absl::uint128 output = 0;
|
|
EXPECT_EQ(i.success, StringToUint128(i.input, &output)) << i.input;
|
|
EXPECT_EQ(i.output, output);
|
|
}
|
|
|
|
// One additional test to verify that conversion of numbers in strings with
|
|
// embedded NUL characters. The NUL and extra data after it should be
|
|
// interpreted as junk after the number.
|
|
const char input[] =
|
|
"6\0"
|
|
"6";
|
|
std::string input_string(input, std::size(input) - 1);
|
|
absl::uint128 output;
|
|
EXPECT_FALSE(StringToUint128(input_string, &output));
|
|
EXPECT_EQ(6U, output);
|
|
}
|
|
|
|
TEST(AbseilStringNumberConversionsTest, HexStringToUInt128) {
|
|
// Test cases adapted from `StringNumberConversionsTest.HexStringToUint64`.
|
|
static const struct {
|
|
std::string input;
|
|
absl::uint128 output;
|
|
bool success;
|
|
} cases[] = {
|
|
{"0", 0, true},
|
|
{"42", 66, true},
|
|
{"-42", 0, false},
|
|
{"+42", 66, true},
|
|
{"ffffffffffffffff",
|
|
absl::MakeUint128(/*high=*/0,
|
|
/*low=*/std::numeric_limits<uint64_t>::max()),
|
|
true},
|
|
{"1ffffffffffffffff",
|
|
absl::MakeUint128(/*high=*/1,
|
|
/*low=*/std::numeric_limits<uint64_t>::max()),
|
|
true},
|
|
{"7fffffff", INT_MAX, true},
|
|
{"-80000000", 0, false},
|
|
{"ffffffff", 0xffffffff, true},
|
|
{"DeadBeef", 0xdeadbeef, true},
|
|
{"0x42", 66, true},
|
|
{"-0x42", 0, false},
|
|
{"+0x42", 66, true},
|
|
{"0xffffffffffffffff",
|
|
absl::MakeUint128(/*high=*/0,
|
|
/*low=*/std::numeric_limits<uint64_t>::max()),
|
|
true},
|
|
{"0x1ffffffffffffffff",
|
|
absl::MakeUint128(/*high=*/1,
|
|
/*low=*/std::numeric_limits<uint64_t>::max()),
|
|
true},
|
|
{"0x7fffffff", INT_MAX, true},
|
|
{"-0x80000000", 0, false},
|
|
{"0xffffffff", 0xffffffff, true},
|
|
{"0XDeadBeef", 0xdeadbeef, true},
|
|
{"0x7fffffffffffffffffffffffffffffff",
|
|
std::numeric_limits<absl::int128>::max(), true},
|
|
{"-0x8000000000000000", 0, false},
|
|
{"0x8000000000000000",
|
|
absl::MakeUint128(/*high=*/0, UINT64_C(0x8000000000000000)), true},
|
|
{"-0x8000000000000001", 0, false},
|
|
{"0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
std::numeric_limits<absl::uint128>::max(), true},
|
|
{"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
std::numeric_limits<absl::uint128>::max(), true},
|
|
{"0x0000000000000000", 0, true},
|
|
{"0000000000000000", 0, true},
|
|
{"1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
|
|
std::numeric_limits<absl::uint128>::max(), false}, // Overflow test.
|
|
{"0x0f", 15, true},
|
|
{"0f", 15, true},
|
|
{" 45", 0x45, false},
|
|
{"\t\n\v\f\r 0x45", 0x45, false},
|
|
{" 45", 0x45, false},
|
|
{"45 ", 0x45, false},
|
|
{"45:", 0x45, false},
|
|
{"efgh", 0xef, false},
|
|
{"0xefgh", 0xef, false},
|
|
{"hgfe", 0, false},
|
|
{"-", 0, false},
|
|
{"", 0, false},
|
|
{"0x", 0, false},
|
|
};
|
|
|
|
for (const auto& i : cases) {
|
|
absl::uint128 output = 0;
|
|
EXPECT_EQ(i.success, HexStringToUInt128(i.input, &output)) << i.input;
|
|
EXPECT_EQ(i.output, output) << i.input;
|
|
}
|
|
// One additional test to verify that conversion of numbers in strings with
|
|
// embedded NUL characters. The NUL and extra data after it should be
|
|
// interpreted as junk after the number.
|
|
const char input[] =
|
|
"0xc0ffee\0"
|
|
"9";
|
|
std::string input_string(input, std::size(input) - 1);
|
|
absl::uint128 output;
|
|
EXPECT_FALSE(HexStringToUInt128(input_string, &output));
|
|
EXPECT_EQ(0xc0ffeeU, output);
|
|
}
|
|
|
|
} // namespace base
|