- add sources.
[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_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