Home | History | Annotate | Download | only in strings
      1 // Copyright (c) 2012 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 "base/strings/string_number_conversions.h"
      6 
      7 #include <errno.h>
      8 #include <limits.h>
      9 #include <stddef.h>
     10 #include <stdint.h>
     11 #include <stdio.h>
     12 
     13 #include <cmath>
     14 #include <limits>
     15 
     16 #include "base/bit_cast.h"
     17 #include "base/format_macros.h"
     18 #include "base/macros.h"
     19 #include "base/strings/stringprintf.h"
     20 #include "base/strings/utf_string_conversions.h"
     21 #include "testing/gtest/include/gtest/gtest.h"
     22 
     23 namespace base {
     24 
     25 namespace {
     26 
     27 template <typename INT>
     28 struct IntToStringTest {
     29   INT num;
     30   const char* sexpected;
     31   const char* uexpected;
     32 };
     33 
     34 }  // namespace
     35 
     36 TEST(StringNumberConversionsTest, IntToString) {
     37   static const IntToStringTest<int> int_tests[] = {
     38       { 0, "0", "0" },
     39       { -1, "-1", "4294967295" },
     40       { std::numeric_limits<int>::max(), "2147483647", "2147483647" },
     41       { std::numeric_limits<int>::min(), "-2147483648", "2147483648" },
     42   };
     43   static const IntToStringTest<int64_t> int64_tests[] = {
     44       {0, "0", "0"},
     45       {-1, "-1", "18446744073709551615"},
     46       {
     47           std::numeric_limits<int64_t>::max(), "9223372036854775807",
     48           "9223372036854775807",
     49       },
     50       {std::numeric_limits<int64_t>::min(), "-9223372036854775808",
     51        "9223372036854775808"},
     52   };
     53 
     54   for (size_t i = 0; i < arraysize(int_tests); ++i) {
     55     const IntToStringTest<int>* test = &int_tests[i];
     56     EXPECT_EQ(IntToString(test->num), test->sexpected);
     57     EXPECT_EQ(IntToString16(test->num), UTF8ToUTF16(test->sexpected));
     58     EXPECT_EQ(UintToString(test->num), test->uexpected);
     59     EXPECT_EQ(UintToString16(test->num), UTF8ToUTF16(test->uexpected));
     60   }
     61   for (size_t i = 0; i < arraysize(int64_tests); ++i) {
     62     const IntToStringTest<int64_t>* test = &int64_tests[i];
     63     EXPECT_EQ(Int64ToString(test->num), test->sexpected);
     64     EXPECT_EQ(Int64ToString16(test->num), UTF8ToUTF16(test->sexpected));
     65     EXPECT_EQ(Uint64ToString(test->num), test->uexpected);
     66     EXPECT_EQ(Uint64ToString16(test->num), UTF8ToUTF16(test->uexpected));
     67   }
     68 }
     69 
     70 TEST(StringNumberConversionsTest, Uint64ToString) {
     71   static const struct {
     72     uint64_t input;
     73     std::string output;
     74   } cases[] = {
     75       {0, "0"},
     76       {42, "42"},
     77       {INT_MAX, "2147483647"},
     78       {std::numeric_limits<uint64_t>::max(), "18446744073709551615"},
     79   };
     80 
     81   for (size_t i = 0; i < arraysize(cases); ++i)
     82     EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
     83 }
     84 
     85 TEST(StringNumberConversionsTest, SizeTToString) {
     86   size_t size_t_max = std::numeric_limits<size_t>::max();
     87   std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max);
     88 
     89   static const struct {
     90     size_t input;
     91     std::string output;
     92   } cases[] = {
     93     {0, "0"},
     94     {9, "9"},
     95     {42, "42"},
     96     {INT_MAX, "2147483647"},
     97     {2147483648U, "2147483648"},
     98 #if SIZE_MAX > 4294967295U
     99     {99999999999U, "99999999999"},
    100 #endif
    101     {size_t_max, size_t_max_string},
    102   };
    103 
    104   for (size_t i = 0; i < arraysize(cases); ++i)
    105     EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
    106 }
    107 
    108 TEST(StringNumberConversionsTest, StringToInt) {
    109   static const struct {
    110     std::string input;
    111     int output;
    112     bool success;
    113   } cases[] = {
    114     {"0", 0, true},
    115     {"42", 42, true},
    116     {"42\x99", 42, false},
    117     {"\x99" "42\x99", 0, false},
    118     {"-2147483648", INT_MIN, true},
    119     {"2147483647", INT_MAX, true},
    120     {"", 0, false},
    121     {" 42", 42, false},
    122     {"42 ", 42, false},
    123     {"\t\n\v\f\r 42", 42, false},
    124     {"blah42", 0, false},
    125     {"42blah", 42, false},
    126     {"blah42blah", 0, false},
    127     {"-273.15", -273, false},
    128     {"+98.6", 98, false},
    129     {"--123", 0, false},
    130     {"++123", 0, false},
    131     {"-+123", 0, false},
    132     {"+-123", 0, false},
    133     {"-", 0, false},
    134     {"-2147483649", INT_MIN, false},
    135     {"-99999999999", INT_MIN, false},
    136     {"2147483648", INT_MAX, false},
    137     {"99999999999", INT_MAX, false},
    138   };
    139 
    140   for (size_t i = 0; i < arraysize(cases); ++i) {
    141     int output = cases[i].output ^ 1;  // Ensure StringToInt wrote something.
    142     EXPECT_EQ(cases[i].success, StringToInt(cases[i].input, &output));
    143     EXPECT_EQ(cases[i].output, output);
    144 
    145     string16 utf16_input = UTF8ToUTF16(cases[i].input);
    146     output = cases[i].output ^ 1;  // Ensure StringToInt wrote something.
    147     EXPECT_EQ(cases[i].success, StringToInt(utf16_input, &output));
    148     EXPECT_EQ(cases[i].output, output);
    149   }
    150 
    151   // One additional test to verify that conversion of numbers in strings with
    152   // embedded NUL characters.  The NUL and extra data after it should be
    153   // interpreted as junk after the number.
    154   const char input[] = "6\06";
    155   std::string input_string(input, arraysize(input) - 1);
    156   int output;
    157   EXPECT_FALSE(StringToInt(input_string, &output));
    158   EXPECT_EQ(6, output);
    159 
    160   string16 utf16_input = UTF8ToUTF16(input_string);
    161   output = 0;
    162   EXPECT_FALSE(StringToInt(utf16_input, &output));
    163   EXPECT_EQ(6, output);
    164 
    165   output = 0;
    166   const char16 negative_wide_input[] = { 0xFF4D, '4', '2', 0};
    167   EXPECT_FALSE(StringToInt(string16(negative_wide_input), &output));
    168   EXPECT_EQ(0, output);
    169 }
    170 
    171 TEST(StringNumberConversionsTest, StringToUint) {
    172   static const struct {
    173     std::string input;
    174     unsigned output;
    175     bool success;
    176   } cases[] = {
    177     {"0", 0, true},
    178     {"42", 42, true},
    179     {"42\x99", 42, false},
    180     {"\x99" "42\x99", 0, false},
    181     {"-2147483648", 0, false},
    182     {"2147483647", INT_MAX, true},
    183     {"", 0, false},
    184     {" 42", 42, false},
    185     {"42 ", 42, false},
    186     {"\t\n\v\f\r 42", 42, false},
    187     {"blah42", 0, false},
    188     {"42blah", 42, false},
    189     {"blah42blah", 0, false},
    190     {"-273.15", 0, false},
    191     {"+98.6", 98, false},
    192     {"--123", 0, false},
    193     {"++123", 0, false},
    194     {"-+123", 0, false},
    195     {"+-123", 0, false},
    196     {"-", 0, false},
    197     {"-2147483649", 0, false},
    198     {"-99999999999", 0, false},
    199     {"4294967295", UINT_MAX, true},
    200     {"4294967296", UINT_MAX, false},
    201     {"99999999999", UINT_MAX, false},
    202   };
    203 
    204   for (size_t i = 0; i < arraysize(cases); ++i) {
    205     unsigned output =
    206         cases[i].output ^ 1;  // Ensure StringToUint wrote something.
    207     EXPECT_EQ(cases[i].success, StringToUint(cases[i].input, &output));
    208     EXPECT_EQ(cases[i].output, output);
    209 
    210     string16 utf16_input = UTF8ToUTF16(cases[i].input);
    211     output = cases[i].output ^ 1;  // Ensure StringToUint wrote something.
    212     EXPECT_EQ(cases[i].success, StringToUint(utf16_input, &output));
    213     EXPECT_EQ(cases[i].output, output);
    214   }
    215 
    216   // One additional test to verify that conversion of numbers in strings with
    217   // embedded NUL characters.  The NUL and extra data after it should be
    218   // interpreted as junk after the number.
    219   const char input[] = "6\06";
    220   std::string input_string(input, arraysize(input) - 1);
    221   unsigned output;
    222   EXPECT_FALSE(StringToUint(input_string, &output));
    223   EXPECT_EQ(6U, output);
    224 
    225   string16 utf16_input = UTF8ToUTF16(input_string);
    226   output = 0;
    227   EXPECT_FALSE(StringToUint(utf16_input, &output));
    228   EXPECT_EQ(6U, output);
    229 
    230   output = 0;
    231   const char16 negative_wide_input[] = { 0xFF4D, '4', '2', 0};
    232   EXPECT_FALSE(StringToUint(string16(negative_wide_input), &output));
    233   EXPECT_EQ(0U, output);
    234 }
    235 
    236 TEST(StringNumberConversionsTest, StringToInt64) {
    237   static const struct {
    238     std::string input;
    239     int64_t output;
    240     bool success;
    241   } cases[] = {
    242       {"0", 0, true},
    243       {"42", 42, true},
    244       {"-2147483648", INT_MIN, true},
    245       {"2147483647", INT_MAX, true},
    246       {"-2147483649", INT64_C(-2147483649), true},
    247       {"-99999999999", INT64_C(-99999999999), true},
    248       {"2147483648", INT64_C(2147483648), true},
    249       {"99999999999", INT64_C(99999999999), true},
    250       {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
    251       {"-9223372036854775808", std::numeric_limits<int64_t>::min(), true},
    252       {"09", 9, true},
    253       {"-09", -9, true},
    254       {"", 0, false},
    255       {" 42", 42, false},
    256       {"42 ", 42, false},
    257       {"0x42", 0, false},
    258       {"\t\n\v\f\r 42", 42, false},
    259       {"blah42", 0, false},
    260       {"42blah", 42, false},
    261       {"blah42blah", 0, false},
    262       {"-273.15", -273, false},
    263       {"+98.6", 98, false},
    264       {"--123", 0, false},
    265       {"++123", 0, false},
    266       {"-+123", 0, false},
    267       {"+-123", 0, false},
    268       {"-", 0, false},
    269       {"-9223372036854775809", std::numeric_limits<int64_t>::min(), false},
    270       {"-99999999999999999999", std::numeric_limits<int64_t>::min(), false},
    271       {"9223372036854775808", std::numeric_limits<int64_t>::max(), false},
    272       {"99999999999999999999", std::numeric_limits<int64_t>::max(), false},
    273   };
    274 
    275   for (size_t i = 0; i < arraysize(cases); ++i) {
    276     int64_t output = 0;
    277     EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output));
    278     EXPECT_EQ(cases[i].output, output);
    279 
    280     string16 utf16_input = UTF8ToUTF16(cases[i].input);
    281     output = 0;
    282     EXPECT_EQ(cases[i].success, StringToInt64(utf16_input, &output));
    283     EXPECT_EQ(cases[i].output, output);
    284   }
    285 
    286   // One additional test to verify that conversion of numbers in strings with
    287   // embedded NUL characters.  The NUL and extra data after it should be
    288   // interpreted as junk after the number.
    289   const char input[] = "6\06";
    290   std::string input_string(input, arraysize(input) - 1);
    291   int64_t output;
    292   EXPECT_FALSE(StringToInt64(input_string, &output));
    293   EXPECT_EQ(6, output);
    294 
    295   string16 utf16_input = UTF8ToUTF16(input_string);
    296   output = 0;
    297   EXPECT_FALSE(StringToInt64(utf16_input, &output));
    298   EXPECT_EQ(6, output);
    299 }
    300 
    301 TEST(StringNumberConversionsTest, StringToUint64) {
    302   static const struct {
    303     std::string input;
    304     uint64_t output;
    305     bool success;
    306   } cases[] = {
    307       {"0", 0, true},
    308       {"42", 42, true},
    309       {"-2147483648", 0, false},
    310       {"2147483647", INT_MAX, true},
    311       {"-2147483649", 0, false},
    312       {"-99999999999", 0, false},
    313       {"2147483648", UINT64_C(2147483648), true},
    314       {"99999999999", UINT64_C(99999999999), true},
    315       {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
    316       {"-9223372036854775808", 0, false},
    317       {"09", 9, true},
    318       {"-09", 0, false},
    319       {"", 0, false},
    320       {" 42", 42, false},
    321       {"42 ", 42, false},
    322       {"0x42", 0, false},
    323       {"\t\n\v\f\r 42", 42, false},
    324       {"blah42", 0, false},
    325       {"42blah", 42, false},
    326       {"blah42blah", 0, false},
    327       {"-273.15", 0, false},
    328       {"+98.6", 98, false},
    329       {"--123", 0, false},
    330       {"++123", 0, false},
    331       {"-+123", 0, false},
    332       {"+-123", 0, false},
    333       {"-", 0, false},
    334       {"-9223372036854775809", 0, false},
    335       {"-99999999999999999999", 0, false},
    336       {"9223372036854775808", UINT64_C(9223372036854775808), true},
    337       {"99999999999999999999", std::numeric_limits<uint64_t>::max(), false},
    338       {"18446744073709551615", std::numeric_limits<uint64_t>::max(), true},
    339       {"18446744073709551616", std::numeric_limits<uint64_t>::max(), false},
    340   };
    341 
    342   for (size_t i = 0; i < arraysize(cases); ++i) {
    343     uint64_t output = 0;
    344     EXPECT_EQ(cases[i].success, StringToUint64(cases[i].input, &output));
    345     EXPECT_EQ(cases[i].output, output);
    346 
    347     string16 utf16_input = UTF8ToUTF16(cases[i].input);
    348     output = 0;
    349     EXPECT_EQ(cases[i].success, StringToUint64(utf16_input, &output));
    350     EXPECT_EQ(cases[i].output, output);
    351   }
    352 
    353   // One additional test to verify that conversion of numbers in strings with
    354   // embedded NUL characters.  The NUL and extra data after it should be
    355   // interpreted as junk after the number.
    356   const char input[] = "6\06";
    357   std::string input_string(input, arraysize(input) - 1);
    358   uint64_t output;
    359   EXPECT_FALSE(StringToUint64(input_string, &output));
    360   EXPECT_EQ(6U, output);
    361 
    362   string16 utf16_input = UTF8ToUTF16(input_string);
    363   output = 0;
    364   EXPECT_FALSE(StringToUint64(utf16_input, &output));
    365   EXPECT_EQ(6U, output);
    366 }
    367 
    368 TEST(StringNumberConversionsTest, StringToSizeT) {
    369   size_t size_t_max = std::numeric_limits<size_t>::max();
    370   std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max);
    371 
    372   static const struct {
    373     std::string input;
    374     size_t output;
    375     bool success;
    376   } cases[] = {
    377     {"0", 0, true},
    378     {"42", 42, true},
    379     {"-2147483648", 0, false},
    380     {"2147483647", INT_MAX, true},
    381     {"-2147483649", 0, false},
    382     {"-99999999999", 0, false},
    383     {"2147483648", 2147483648U, true},
    384 #if SIZE_MAX > 4294967295U
    385     {"99999999999", 99999999999U, true},
    386 #endif
    387     {"-9223372036854775808", 0, false},
    388     {"09", 9, true},
    389     {"-09", 0, false},
    390     {"", 0, false},
    391     {" 42", 42, false},
    392     {"42 ", 42, false},
    393     {"0x42", 0, false},
    394     {"\t\n\v\f\r 42", 42, false},
    395     {"blah42", 0, false},
    396     {"42blah", 42, false},
    397     {"blah42blah", 0, false},
    398     {"-273.15", 0, false},
    399     {"+98.6", 98, false},
    400     {"--123", 0, false},
    401     {"++123", 0, false},
    402     {"-+123", 0, false},
    403     {"+-123", 0, false},
    404     {"-", 0, false},
    405     {"-9223372036854775809", 0, false},
    406     {"-99999999999999999999", 0, false},
    407     {"999999999999999999999999", size_t_max, false},
    408     {size_t_max_string, size_t_max, true},
    409   };
    410 
    411   for (size_t i = 0; i < arraysize(cases); ++i) {
    412     size_t output = 0;
    413     EXPECT_EQ(cases[i].success, StringToSizeT(cases[i].input, &output));
    414     EXPECT_EQ(cases[i].output, output);
    415 
    416     string16 utf16_input = UTF8ToUTF16(cases[i].input);
    417     output = 0;
    418     EXPECT_EQ(cases[i].success, StringToSizeT(utf16_input, &output));
    419     EXPECT_EQ(cases[i].output, output);
    420   }
    421 
    422   // One additional test to verify that conversion of numbers in strings with
    423   // embedded NUL characters.  The NUL and extra data after it should be
    424   // interpreted as junk after the number.
    425   const char input[] = "6\06";
    426   std::string input_string(input, arraysize(input) - 1);
    427   size_t output;
    428   EXPECT_FALSE(StringToSizeT(input_string, &output));
    429   EXPECT_EQ(6U, output);
    430 
    431   string16 utf16_input = UTF8ToUTF16(input_string);
    432   output = 0;
    433   EXPECT_FALSE(StringToSizeT(utf16_input, &output));
    434   EXPECT_EQ(6U, output);
    435 }
    436 
    437 TEST(StringNumberConversionsTest, HexStringToInt) {
    438   static const struct {
    439     std::string input;
    440     int64_t output;
    441     bool success;
    442   } cases[] = {
    443     {"0", 0, true},
    444     {"42", 66, true},
    445     {"-42", -66, true},
    446     {"+42", 66, true},
    447     {"7fffffff", INT_MAX, true},
    448     {"-80000000", INT_MIN, true},
    449     {"80000000", INT_MAX, false},  // Overflow test.
    450     {"-80000001", INT_MIN, false},  // Underflow test.
    451     {"0x42", 66, true},
    452     {"-0x42", -66, true},
    453     {"+0x42", 66, true},
    454     {"0x7fffffff", INT_MAX, true},
    455     {"-0x80000000", INT_MIN, true},
    456     {"-80000000", INT_MIN, true},
    457     {"80000000", INT_MAX, false},  // Overflow test.
    458     {"-80000001", INT_MIN, false},  // Underflow test.
    459     {"0x0f", 15, true},
    460     {"0f", 15, true},
    461     {" 45", 0x45, false},
    462     {"\t\n\v\f\r 0x45", 0x45, false},
    463     {" 45", 0x45, false},
    464     {"45 ", 0x45, false},
    465     {"45:", 0x45, false},
    466     {"efgh", 0xef, false},
    467     {"0xefgh", 0xef, false},
    468     {"hgfe", 0, false},
    469     {"-", 0, false},
    470     {"", 0, false},
    471     {"0x", 0, false},
    472   };
    473 
    474   for (size_t i = 0; i < arraysize(cases); ++i) {
    475     int output = 0;
    476     EXPECT_EQ(cases[i].success, HexStringToInt(cases[i].input, &output));
    477     EXPECT_EQ(cases[i].output, output);
    478   }
    479   // One additional test to verify that conversion of numbers in strings with
    480   // embedded NUL characters.  The NUL and extra data after it should be
    481   // interpreted as junk after the number.
    482   const char input[] = "0xc0ffee\0" "9";
    483   std::string input_string(input, arraysize(input) - 1);
    484   int output;
    485   EXPECT_FALSE(HexStringToInt(input_string, &output));
    486   EXPECT_EQ(0xc0ffee, output);
    487 }
    488 
    489 TEST(StringNumberConversionsTest, HexStringToUInt) {
    490   static const struct {
    491     std::string input;
    492     uint32_t output;
    493     bool success;
    494   } cases[] = {
    495       {"0", 0, true},
    496       {"42", 0x42, true},
    497       {"-42", 0, false},
    498       {"+42", 0x42, true},
    499       {"7fffffff", INT_MAX, true},
    500       {"-80000000", 0, false},
    501       {"ffffffff", 0xffffffff, true},
    502       {"DeadBeef", 0xdeadbeef, true},
    503       {"0x42", 0x42, true},
    504       {"-0x42", 0, false},
    505       {"+0x42", 0x42, true},
    506       {"0x7fffffff", INT_MAX, true},
    507       {"-0x80000000", 0, false},
    508       {"0xffffffff", std::numeric_limits<uint32_t>::max(), true},
    509       {"0XDeadBeef", 0xdeadbeef, true},
    510       {"0x7fffffffffffffff", std::numeric_limits<uint32_t>::max(),
    511        false},  // Overflow test.
    512       {"-0x8000000000000000", 0, false},
    513       {"0x8000000000000000", std::numeric_limits<uint32_t>::max(),
    514        false},  // Overflow test.
    515       {"-0x8000000000000001", 0, false},
    516       {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
    517        false},  // Overflow test.
    518       {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
    519        false},  // Overflow test.
    520       {"0x0000000000000000", 0, true},
    521       {"0000000000000000", 0, true},
    522       {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
    523        false},  // Overflow test.
    524       {"0x0f", 0x0f, true},
    525       {"0f", 0x0f, true},
    526       {" 45", 0x45, false},
    527       {"\t\n\v\f\r 0x45", 0x45, false},
    528       {" 45", 0x45, false},
    529       {"45 ", 0x45, false},
    530       {"45:", 0x45, false},
    531       {"efgh", 0xef, false},
    532       {"0xefgh", 0xef, false},
    533       {"hgfe", 0, false},
    534       {"-", 0, false},
    535       {"", 0, false},
    536       {"0x", 0, false},
    537   };
    538 
    539   for (size_t i = 0; i < arraysize(cases); ++i) {
    540     uint32_t output = 0;
    541     EXPECT_EQ(cases[i].success, HexStringToUInt(cases[i].input, &output));
    542     EXPECT_EQ(cases[i].output, output);
    543   }
    544   // One additional test to verify that conversion of numbers in strings with
    545   // embedded NUL characters.  The NUL and extra data after it should be
    546   // interpreted as junk after the number.
    547   const char input[] = "0xc0ffee\0" "9";
    548   std::string input_string(input, arraysize(input) - 1);
    549   uint32_t output;
    550   EXPECT_FALSE(HexStringToUInt(input_string, &output));
    551   EXPECT_EQ(0xc0ffeeU, output);
    552 }
    553 
    554 TEST(StringNumberConversionsTest, HexStringToInt64) {
    555   static const struct {
    556     std::string input;
    557     int64_t output;
    558     bool success;
    559   } cases[] = {
    560       {"0", 0, true},
    561       {"42", 66, true},
    562       {"-42", -66, true},
    563       {"+42", 66, true},
    564       {"40acd88557b", INT64_C(4444444448123), true},
    565       {"7fffffff", INT_MAX, true},
    566       {"-80000000", INT_MIN, true},
    567       {"ffffffff", 0xffffffff, true},
    568       {"DeadBeef", 0xdeadbeef, true},
    569       {"0x42", 66, true},
    570       {"-0x42", -66, true},
    571       {"+0x42", 66, true},
    572       {"0x40acd88557b", INT64_C(4444444448123), true},
    573       {"0x7fffffff", INT_MAX, true},
    574       {"-0x80000000", INT_MIN, true},
    575       {"0xffffffff", 0xffffffff, true},
    576       {"0XDeadBeef", 0xdeadbeef, true},
    577       {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true},
    578       {"-0x8000000000000000", std::numeric_limits<int64_t>::min(), true},
    579       {"0x8000000000000000", std::numeric_limits<int64_t>::max(),
    580        false},  // Overflow test.
    581       {"-0x8000000000000001", std::numeric_limits<int64_t>::min(),
    582        false},  // Underflow test.
    583       {"0x0f", 15, true},
    584       {"0f", 15, true},
    585       {" 45", 0x45, false},
    586       {"\t\n\v\f\r 0x45", 0x45, false},
    587       {" 45", 0x45, false},
    588       {"45 ", 0x45, false},
    589       {"45:", 0x45, false},
    590       {"efgh", 0xef, false},
    591       {"0xefgh", 0xef, false},
    592       {"hgfe", 0, false},
    593       {"-", 0, false},
    594       {"", 0, false},
    595       {"0x", 0, false},
    596   };
    597 
    598   for (size_t i = 0; i < arraysize(cases); ++i) {
    599     int64_t output = 0;
    600     EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output));
    601     EXPECT_EQ(cases[i].output, output);
    602   }
    603   // One additional test to verify that conversion of numbers in strings with
    604   // embedded NUL characters.  The NUL and extra data after it should be
    605   // interpreted as junk after the number.
    606   const char input[] = "0xc0ffee\0" "9";
    607   std::string input_string(input, arraysize(input) - 1);
    608   int64_t output;
    609   EXPECT_FALSE(HexStringToInt64(input_string, &output));
    610   EXPECT_EQ(0xc0ffee, output);
    611 }
    612 
    613 TEST(StringNumberConversionsTest, HexStringToUInt64) {
    614   static const struct {
    615     std::string input;
    616     uint64_t output;
    617     bool success;
    618   } cases[] = {
    619       {"0", 0, true},
    620       {"42", 66, true},
    621       {"-42", 0, false},
    622       {"+42", 66, true},
    623       {"40acd88557b", INT64_C(4444444448123), true},
    624       {"7fffffff", INT_MAX, true},
    625       {"-80000000", 0, false},
    626       {"ffffffff", 0xffffffff, true},
    627       {"DeadBeef", 0xdeadbeef, true},
    628       {"0x42", 66, true},
    629       {"-0x42", 0, false},
    630       {"+0x42", 66, true},
    631       {"0x40acd88557b", INT64_C(4444444448123), true},
    632       {"0x7fffffff", INT_MAX, true},
    633       {"-0x80000000", 0, false},
    634       {"0xffffffff", 0xffffffff, true},
    635       {"0XDeadBeef", 0xdeadbeef, true},
    636       {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true},
    637       {"-0x8000000000000000", 0, false},
    638       {"0x8000000000000000", UINT64_C(0x8000000000000000), true},
    639       {"-0x8000000000000001", 0, false},
    640       {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true},
    641       {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true},
    642       {"0x0000000000000000", 0, true},
    643       {"0000000000000000", 0, true},
    644       {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(),
    645        false},  // Overflow test.
    646       {"0x0f", 15, true},
    647       {"0f", 15, true},
    648       {" 45", 0x45, false},
    649       {"\t\n\v\f\r 0x45", 0x45, false},
    650       {" 45", 0x45, false},
    651       {"45 ", 0x45, false},
    652       {"45:", 0x45, false},
    653       {"efgh", 0xef, false},
    654       {"0xefgh", 0xef, false},
    655       {"hgfe", 0, false},
    656       {"-", 0, false},
    657       {"", 0, false},
    658       {"0x", 0, false},
    659   };
    660 
    661   for (size_t i = 0; i < arraysize(cases); ++i) {
    662     uint64_t output = 0;
    663     EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output));
    664     EXPECT_EQ(cases[i].output, output);
    665   }
    666   // One additional test to verify that conversion of numbers in strings with
    667   // embedded NUL characters.  The NUL and extra data after it should be
    668   // interpreted as junk after the number.
    669   const char input[] = "0xc0ffee\0" "9";
    670   std::string input_string(input, arraysize(input) - 1);
    671   uint64_t output;
    672   EXPECT_FALSE(HexStringToUInt64(input_string, &output));
    673   EXPECT_EQ(0xc0ffeeU, output);
    674 }
    675 
    676 TEST(StringNumberConversionsTest, HexStringToBytes) {
    677   static const struct {
    678     const std::string input;
    679     const char* output;
    680     size_t output_len;
    681     bool success;
    682   } cases[] = {
    683     {"0", "", 0, false},  // odd number of characters fails
    684     {"00", "\0", 1, true},
    685     {"42", "\x42", 1, true},
    686     {"-42", "", 0, false},  // any non-hex value fails
    687     {"+42", "", 0, false},
    688     {"7fffffff", "\x7f\xff\xff\xff", 4, true},
    689     {"80000000", "\x80\0\0\0", 4, true},
    690     {"deadbeef", "\xde\xad\xbe\xef", 4, true},
    691     {"DeadBeef", "\xde\xad\xbe\xef", 4, true},
    692     {"0x42", "", 0, false},  // leading 0x fails (x is not hex)
    693     {"0f", "\xf", 1, true},
    694     {"45  ", "\x45", 1, false},
    695     {"efgh", "\xef", 1, false},
    696     {"", "", 0, false},
    697     {"0123456789ABCDEF", "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8, true},
    698     {"0123456789ABCDEF012345",
    699      "\x01\x23\x45\x67\x89\xAB\xCD\xEF\x01\x23\x45", 11, true},
    700   };
    701 
    702 
    703   for (size_t i = 0; i < arraysize(cases); ++i) {
    704     std::vector<uint8_t> output;
    705     std::vector<uint8_t> compare;
    706     EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) <<
    707         i << ": " << cases[i].input;
    708     for (size_t j = 0; j < cases[i].output_len; ++j)
    709       compare.push_back(static_cast<uint8_t>(cases[i].output[j]));
    710     ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input;
    711     EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) <<
    712         i << ": " << cases[i].input;
    713   }
    714 }
    715 
    716 TEST(StringNumberConversionsTest, StringToDouble) {
    717   static const struct {
    718     std::string input;
    719     double output;
    720     bool success;
    721   } cases[] = {
    722     {"0", 0.0, true},
    723     {"42", 42.0, true},
    724     {"-42", -42.0, true},
    725     {"123.45", 123.45, true},
    726     {"-123.45", -123.45, true},
    727     {"+123.45", 123.45, true},
    728     {"2.99792458e8", 299792458.0, true},
    729     {"149597870.691E+3", 149597870691.0, true},
    730     {"6.", 6.0, true},
    731     {"9e99999999999999999999", std::numeric_limits<double>::infinity(),
    732                                false},
    733     {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(),
    734                                 false},
    735     {"1e-2", 0.01, true},
    736     {"42 ", 42.0, false},
    737     {" 1e-2", 0.01, false},
    738     {"1e-2 ", 0.01, false},
    739     {"-1E-7", -0.0000001, true},
    740     {"01e02", 100, true},
    741     {"2.3e15", 2.3e15, true},
    742     {"\t\n\v\f\r -123.45e2", -12345.0, false},
    743     {"+123 e4", 123.0, false},
    744     {"123e ", 123.0, false},
    745     {"123e", 123.0, false},
    746     {" 2.99", 2.99, false},
    747     {"1e3.4", 1000.0, false},
    748     {"nothing", 0.0, false},
    749     {"-", 0.0, false},
    750     {"+", 0.0, false},
    751     {"", 0.0, false},
    752   };
    753 
    754   for (size_t i = 0; i < arraysize(cases); ++i) {
    755     double output;
    756     errno = 1;
    757     EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output))
    758         << "for input=" << cases[i].input << "got output=" << output;
    759     if (cases[i].success)
    760       EXPECT_EQ(1, errno) << i;  // confirm that errno is unchanged.
    761     EXPECT_DOUBLE_EQ(cases[i].output, output);
    762   }
    763 
    764   // One additional test to verify that conversion of numbers in strings with
    765   // embedded NUL characters.  The NUL and extra data after it should be
    766   // interpreted as junk after the number.
    767   const char input[] = "3.14\0" "159";
    768   std::string input_string(input, arraysize(input) - 1);
    769   double output;
    770   EXPECT_FALSE(StringToDouble(input_string, &output));
    771   EXPECT_DOUBLE_EQ(3.14, output);
    772 }
    773 
    774 TEST(StringNumberConversionsTest, DoubleToString) {
    775   static const struct {
    776     double input;
    777     const char* expected;
    778   } cases[] = {
    779     {0.0, "0.0"},
    780     {1.25, "1.25"},
    781     {1.33518e+012, "1335180000000.0"},
    782     {1.33489e+012, "1334890000000.0"},
    783     {1.33505e+012, "1335050000000.0"},
    784     {1.33545e+009, "1335450000.0"},
    785     {1.33503e+009, "1335030000.0"},
    786   };
    787 
    788   for (size_t i = 0; i < arraysize(cases); ++i) {
    789     EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input));
    790   }
    791 
    792   // The following two values were seen in crashes in the wild.
    793   const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'};
    794   double input = 0;
    795   memcpy(&input, input_bytes, arraysize(input_bytes));
    796   EXPECT_EQ("1335179083776.0", DoubleToString(input));
    797   const char input_bytes2[8] =
    798       {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'};
    799   input = 0;
    800   memcpy(&input, input_bytes2, arraysize(input_bytes2));
    801   EXPECT_EQ("1334890332160.0", DoubleToString(input));
    802 }
    803 
    804 TEST(StringNumberConversionsTest, HexEncode) {
    805   std::string hex(HexEncode(NULL, 0));
    806   EXPECT_EQ(hex.length(), 0U);
    807   unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
    808   hex = HexEncode(bytes, sizeof(bytes));
    809   EXPECT_EQ(hex.compare("01FF02FE038081"), 0);
    810 }
    811 
    812 }  // namespace base
    813