Notify network properties changed for IPConfig updates
[chromium-blink-merge.git] / base / strings / string_number_conversions_unittest.cc
blob271c6bb7b801d0ddaa2be00d149f62d180a279ef
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, 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);
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},
99 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i)
100 EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input));
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},
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);
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);
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);
155 string16 utf16_input = UTF8ToUTF16(input_string);
156 output = 0;
157 EXPECT_FALSE(StringToInt(utf16_input, &output));
158 EXPECT_EQ(6, output);
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);
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},
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);
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);
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);
219 string16 utf16_input = UTF8ToUTF16(input_string);
220 output = 0;
221 EXPECT_FALSE(StringToUint(utf16_input, &output));
222 EXPECT_EQ(6U, output);
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);
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},
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);
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);
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);
289 string16 utf16_input = UTF8ToUTF16(input_string);
290 output = 0;
291 EXPECT_FALSE(StringToInt64(utf16_input, &output));
292 EXPECT_EQ(6, output);
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},
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);
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);
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);
356 string16 utf16_input = UTF8ToUTF16(input_string);
357 output = 0;
358 EXPECT_FALSE(StringToUint64(utf16_input, &output));
359 EXPECT_EQ(6U, output);
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);
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},
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);
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);
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);
425 string16 utf16_input = UTF8ToUTF16(input_string);
426 output = 0;
427 EXPECT_FALSE(StringToSizeT(utf16_input, &output));
428 EXPECT_EQ(6U, output);
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},
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);
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\09";
477 std::string input_string(input, arraysize(input) - 1);
478 int output;
479 EXPECT_FALSE(HexStringToInt(input_string, &output));
480 EXPECT_EQ(0xc0ffee, output);
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},
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);
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\09";
537 std::string input_string(input, arraysize(input) - 1);
538 uint32 output;
539 EXPECT_FALSE(HexStringToUInt(input_string, &output));
540 EXPECT_EQ(0xc0ffeeU, output);
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},
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);
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\09";
594 std::string input_string(input, arraysize(input) - 1);
595 int64 output;
596 EXPECT_FALSE(HexStringToInt64(input_string, &output));
597 EXPECT_EQ(0xc0ffee, output);
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},
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);
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\09";
656 std::string input_string(input, arraysize(input) - 1);
657 uint64 output;
658 EXPECT_FALSE(HexStringToUInt64(input_string, &output));
659 EXPECT_EQ(0xc0ffeeU, output);
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},
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;
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},
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);
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\0159";
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);
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"},
771 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) {
772 EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input));
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));
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);
795 } // namespace base