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