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, HexStringToInt64) {
    462   static const struct {
    463     std::string input;
    464     int64 output;
    465     bool success;
    466   } cases[] = {
    467     {"0", 0, true},
    468     {"42", 66, true},
    469     {"-42", -66, true},
    470     {"+42", 66, true},
    471     {"40acd88557b", GG_INT64_C(4444444448123), true},
    472     {"7fffffff", INT_MAX, true},
    473     {"-80000000", INT_MIN, true},
    474     {"ffffffff", 0xffffffff, true},
    475     {"DeadBeef", 0xdeadbeef, true},
    476     {"0x42", 66, true},
    477     {"-0x42", -66, true},
    478     {"+0x42", 66, true},
    479     {"0x40acd88557b", GG_INT64_C(4444444448123), true},
    480     {"0x7fffffff", INT_MAX, true},
    481     {"-0x80000000", INT_MIN, true},
    482     {"0xffffffff", 0xffffffff, true},
    483     {"0XDeadBeef", 0xdeadbeef, true},
    484     {"0x7fffffffffffffff", kint64max, true},
    485     {"-0x8000000000000000", kint64min, true},
    486     {"0x8000000000000000", kint64max, false},  // Overflow test.
    487     {"-0x8000000000000001", kint64min, false},  // Underflow test.
    488     {"0x0f", 15, true},
    489     {"0f", 15, true},
    490     {" 45", 0x45, false},
    491     {"\t\n\v\f\r 0x45", 0x45, false},
    492     {" 45", 0x45, false},
    493     {"45 ", 0x45, false},
    494     {"45:", 0x45, false},
    495     {"efgh", 0xef, false},
    496     {"0xefgh", 0xef, false},
    497     {"hgfe", 0, false},
    498     {"-", 0, false},
    499     {"", 0, false},
    500     {"0x", 0, false},
    501   };
    502 
    503   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    504     int64 output = 0;
    505     EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output));
    506     EXPECT_EQ(cases[i].output, output);
    507   }
    508   // One additional test to verify that conversion of numbers in strings with
    509   // embedded NUL characters.  The NUL and extra data after it should be
    510   // interpreted as junk after the number.
    511   const char input[] = "0xc0ffee\09";
    512   std::string input_string(input, arraysize(input) - 1);
    513   int64 output;
    514   EXPECT_FALSE(HexStringToInt64(input_string, &output));
    515   EXPECT_EQ(0xc0ffee, output);
    516 }
    517 
    518 TEST(StringNumberConversionsTest, HexStringToUInt64) {
    519   static const struct {
    520     std::string input;
    521     uint64 output;
    522     bool success;
    523   } cases[] = {
    524     {"0", 0, true},
    525     {"42", 66, true},
    526     {"-42", 0, false},
    527     {"+42", 66, true},
    528     {"40acd88557b", GG_INT64_C(4444444448123), true},
    529     {"7fffffff", INT_MAX, true},
    530     {"-80000000", 0, false},
    531     {"ffffffff", 0xffffffff, true},
    532     {"DeadBeef", 0xdeadbeef, true},
    533     {"0x42", 66, true},
    534     {"-0x42", 0, false},
    535     {"+0x42", 66, true},
    536     {"0x40acd88557b", GG_INT64_C(4444444448123), true},
    537     {"0x7fffffff", INT_MAX, true},
    538     {"-0x80000000", 0, false},
    539     {"0xffffffff", 0xffffffff, true},
    540     {"0XDeadBeef", 0xdeadbeef, true},
    541     {"0x7fffffffffffffff", kint64max, true},
    542     {"-0x8000000000000000", 0, false},
    543     {"0x8000000000000000", GG_UINT64_C(0x8000000000000000), true},
    544     {"-0x8000000000000001", 0, false},
    545     {"0xFFFFFFFFFFFFFFFF", kuint64max, true},
    546     {"FFFFFFFFFFFFFFFF", kuint64max, true},
    547     {"0x0000000000000000", 0, true},
    548     {"0000000000000000", 0, true},
    549     {"1FFFFFFFFFFFFFFFF", kuint64max, false}, // Overflow test.
    550     {"0x0f", 15, true},
    551     {"0f", 15, true},
    552     {" 45", 0x45, false},
    553     {"\t\n\v\f\r 0x45", 0x45, false},
    554     {" 45", 0x45, false},
    555     {"45 ", 0x45, false},
    556     {"45:", 0x45, false},
    557     {"efgh", 0xef, false},
    558     {"0xefgh", 0xef, false},
    559     {"hgfe", 0, false},
    560     {"-", 0, false},
    561     {"", 0, false},
    562     {"0x", 0, false},
    563   };
    564 
    565   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    566     uint64 output = 0;
    567     EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output));
    568     EXPECT_EQ(cases[i].output, output);
    569   }
    570   // One additional test to verify that conversion of numbers in strings with
    571   // embedded NUL characters.  The NUL and extra data after it should be
    572   // interpreted as junk after the number.
    573   const char input[] = "0xc0ffee\09";
    574   std::string input_string(input, arraysize(input) - 1);
    575   uint64 output;
    576   EXPECT_FALSE(HexStringToUInt64(input_string, &output));
    577   EXPECT_EQ(0xc0ffeeU, output);
    578 }
    579 
    580 TEST(StringNumberConversionsTest, HexStringToBytes) {
    581   static const struct {
    582     const std::string input;
    583     const char* output;
    584     size_t output_len;
    585     bool success;
    586   } cases[] = {
    587     {"0", "", 0, false},  // odd number of characters fails
    588     {"00", "\0", 1, true},
    589     {"42", "\x42", 1, true},
    590     {"-42", "", 0, false},  // any non-hex value fails
    591     {"+42", "", 0, false},
    592     {"7fffffff", "\x7f\xff\xff\xff", 4, true},
    593     {"80000000", "\x80\0\0\0", 4, true},
    594     {"deadbeef", "\xde\xad\xbe\xef", 4, true},
    595     {"DeadBeef", "\xde\xad\xbe\xef", 4, true},
    596     {"0x42", "", 0, false},  // leading 0x fails (x is not hex)
    597     {"0f", "\xf", 1, true},
    598     {"45  ", "\x45", 1, false},
    599     {"efgh", "\xef", 1, false},
    600     {"", "", 0, false},
    601     {"0123456789ABCDEF", "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8, true},
    602     {"0123456789ABCDEF012345",
    603      "\x01\x23\x45\x67\x89\xAB\xCD\xEF\x01\x23\x45", 11, true},
    604   };
    605 
    606 
    607   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    608     std::vector<uint8> output;
    609     std::vector<uint8> compare;
    610     EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) <<
    611         i << ": " << cases[i].input;
    612     for (size_t j = 0; j < cases[i].output_len; ++j)
    613       compare.push_back(static_cast<uint8>(cases[i].output[j]));
    614     ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input;
    615     EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) <<
    616         i << ": " << cases[i].input;
    617   }
    618 }
    619 
    620 TEST(StringNumberConversionsTest, StringToDouble) {
    621   static const struct {
    622     std::string input;
    623     double output;
    624     bool success;
    625   } cases[] = {
    626     {"0", 0.0, true},
    627     {"42", 42.0, true},
    628     {"-42", -42.0, true},
    629     {"123.45", 123.45, true},
    630     {"-123.45", -123.45, true},
    631     {"+123.45", 123.45, true},
    632     {"2.99792458e8", 299792458.0, true},
    633     {"149597870.691E+3", 149597870691.0, true},
    634     {"6.", 6.0, true},
    635     {"9e99999999999999999999", HUGE_VAL, false},
    636     {"-9e99999999999999999999", -HUGE_VAL, false},
    637     {"1e-2", 0.01, true},
    638     {"42 ", 42.0, false},
    639     {" 1e-2", 0.01, false},
    640     {"1e-2 ", 0.01, false},
    641     {"-1E-7", -0.0000001, true},
    642     {"01e02", 100, true},
    643     {"2.3e15", 2.3e15, true},
    644     {"\t\n\v\f\r -123.45e2", -12345.0, false},
    645     {"+123 e4", 123.0, false},
    646     {"123e ", 123.0, false},
    647     {"123e", 123.0, false},
    648     {" 2.99", 2.99, false},
    649     {"1e3.4", 1000.0, false},
    650     {"nothing", 0.0, false},
    651     {"-", 0.0, false},
    652     {"+", 0.0, false},
    653     {"", 0.0, false},
    654   };
    655 
    656   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    657     double output;
    658     errno = 1;
    659     EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output));
    660     if (cases[i].success)
    661       EXPECT_EQ(1, errno) << i;  // confirm that errno is unchanged.
    662     EXPECT_DOUBLE_EQ(cases[i].output, output);
    663   }
    664 
    665   // One additional test to verify that conversion of numbers in strings with
    666   // embedded NUL characters.  The NUL and extra data after it should be
    667   // interpreted as junk after the number.
    668   const char input[] = "3.14\0159";
    669   std::string input_string(input, arraysize(input) - 1);
    670   double output;
    671   EXPECT_FALSE(StringToDouble(input_string, &output));
    672   EXPECT_DOUBLE_EQ(3.14, output);
    673 }
    674 
    675 TEST(StringNumberConversionsTest, DoubleToString) {
    676   static const struct {
    677     double input;
    678     const char* expected;
    679   } cases[] = {
    680     {0.0, "0"},
    681     {1.25, "1.25"},
    682     {1.33518e+012, "1.33518e+12"},
    683     {1.33489e+012, "1.33489e+12"},
    684     {1.33505e+012, "1.33505e+12"},
    685     {1.33545e+009, "1335450000"},
    686     {1.33503e+009, "1335030000"},
    687   };
    688 
    689   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
    690     EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input));
    691   }
    692 
    693   // The following two values were seen in crashes in the wild.
    694   const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'};
    695   double input = 0;
    696   memcpy(&input, input_bytes, arraysize(input_bytes));
    697   EXPECT_EQ("1335179083776", DoubleToString(input));
    698   const char input_bytes2[8] =
    699       {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'};
    700   input = 0;
    701   memcpy(&input, input_bytes2, arraysize(input_bytes2));
    702   EXPECT_EQ("1334890332160", DoubleToString(input));
    703 }
    704 
    705 TEST(StringNumberConversionsTest, HexEncode) {
    706   std::string hex(HexEncode(NULL, 0));
    707   EXPECT_EQ(hex.length(), 0U);
    708   unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
    709   hex = HexEncode(bytes, sizeof(bytes));
    710   EXPECT_EQ(hex.compare("01FF02FE038081"), 0);
    711 }
    712 
    713 }  // namespace base
    714