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
18namespace base {
19
20namespace {
21
22template <typename INT>
23struct IntToStringTest {
24  INT num;
25  const char* sexpected;
26  const char* uexpected;
27};
28
29}  // namespace
30
31TEST(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
65TEST(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
80TEST(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_UNSAFE(cases); ++i)
100    EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
101}
102
103TEST(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_UNSAFE(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
166TEST(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_UNSAFE(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
230TEST(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_UNSAFE(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
295TEST(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_UNSAFE(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
362TEST(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_UNSAFE(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
431TEST(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_UNSAFE(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
483TEST(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_UNSAFE(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
543TEST(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_UNSAFE(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
600TEST(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_UNSAFE(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
662TEST(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_UNSAFE(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
702TEST(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_UNSAFE(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
757TEST(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_UNSAFE(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
787TEST(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
796