[Android] Out with the Android GR, in with the new unified C++ GR
[chromium-blink-merge.git] / base / strings / string_number_conversions_unittest.cc
blobb6e5f961ce26f4d586f5f1de88cd65d644592109
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.
5 #include <errno.h>
6 #include <stdint.h>
7 #include <stdio.h>
9 #include <cmath>
10 #include <limits>
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"
18 namespace base {
20 namespace {
22 template <typename INT>
23 struct IntToStringTest {
24 INT num;
25 const char* sexpected;
26 const char* uexpected;
29 } // namespace
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" },
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" },
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));
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));
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"},
76 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
77 EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
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},
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);
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);
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);
132 string16 utf16_input = UTF8ToUTF16(input_string);
133 output = 0;
134 EXPECT_FALSE(StringToInt(utf16_input, &output));
135 EXPECT_EQ(6, output);
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);
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},
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);
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);
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);
196 string16 utf16_input = UTF8ToUTF16(input_string);
197 output = 0;
198 EXPECT_FALSE(StringToUint(utf16_input, &output));
199 EXPECT_EQ(6U, output);
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);
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},
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);
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);
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);
266 string16 utf16_input = UTF8ToUTF16(input_string);
267 output = 0;
268 EXPECT_FALSE(StringToInt64(utf16_input, &output));
269 EXPECT_EQ(6, output);
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},
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);
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);
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);
333 string16 utf16_input = UTF8ToUTF16(input_string);
334 output = 0;
335 EXPECT_FALSE(StringToUint64(utf16_input, &output));
336 EXPECT_EQ(6U, output);
339 TEST(StringNumberConversionsTest, StringToSizeT) {
341 size_t size_t_max = std::numeric_limits<size_t>::max();
342 std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max);
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},
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);
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);
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);
403 string16 utf16_input = UTF8ToUTF16(input_string);
404 output = 0;
405 EXPECT_FALSE(StringToSizeT(utf16_input, &output));
406 EXPECT_EQ(6U, output);
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},
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);
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);
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},
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);
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);
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},
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);
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);
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},
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);
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);
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},
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;
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},
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);
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);
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"},
749 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
750 EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input));
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));
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);
773 } // namespace base