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