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