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, HexStringToInt64) { 462 static const struct { 463 std::string input; 464 int64 output; 465 bool success; 466 } cases[] = { 467 {"0", 0, true}, 468 {"42", 66, true}, 469 {"-42", -66, true}, 470 {"+42", 66, true}, 471 {"40acd88557b", GG_INT64_C(4444444448123), true}, 472 {"7fffffff", INT_MAX, true}, 473 {"-80000000", INT_MIN, true}, 474 {"ffffffff", 0xffffffff, true}, 475 {"DeadBeef", 0xdeadbeef, true}, 476 {"0x42", 66, true}, 477 {"-0x42", -66, true}, 478 {"+0x42", 66, true}, 479 {"0x40acd88557b", GG_INT64_C(4444444448123), true}, 480 {"0x7fffffff", INT_MAX, true}, 481 {"-0x80000000", INT_MIN, true}, 482 {"0xffffffff", 0xffffffff, true}, 483 {"0XDeadBeef", 0xdeadbeef, true}, 484 {"0x7fffffffffffffff", kint64max, true}, 485 {"-0x8000000000000000", kint64min, true}, 486 {"0x8000000000000000", kint64max, false}, // Overflow test. 487 {"-0x8000000000000001", kint64min, false}, // Underflow test. 488 {"0x0f", 15, true}, 489 {"0f", 15, true}, 490 {" 45", 0x45, false}, 491 {"\t\n\v\f\r 0x45", 0x45, false}, 492 {" 45", 0x45, false}, 493 {"45 ", 0x45, false}, 494 {"45:", 0x45, false}, 495 {"efgh", 0xef, false}, 496 {"0xefgh", 0xef, false}, 497 {"hgfe", 0, false}, 498 {"-", 0, false}, 499 {"", 0, false}, 500 {"0x", 0, false}, 501 }; 502 503 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 504 int64 output = 0; 505 EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output)); 506 EXPECT_EQ(cases[i].output, output); 507 } 508 // One additional test to verify that conversion of numbers in strings with 509 // embedded NUL characters. The NUL and extra data after it should be 510 // interpreted as junk after the number. 511 const char input[] = "0xc0ffee\09"; 512 std::string input_string(input, arraysize(input) - 1); 513 int64 output; 514 EXPECT_FALSE(HexStringToInt64(input_string, &output)); 515 EXPECT_EQ(0xc0ffee, output); 516 } 517 518 TEST(StringNumberConversionsTest, HexStringToUInt64) { 519 static const struct { 520 std::string input; 521 uint64 output; 522 bool success; 523 } cases[] = { 524 {"0", 0, true}, 525 {"42", 66, true}, 526 {"-42", 0, false}, 527 {"+42", 66, true}, 528 {"40acd88557b", GG_INT64_C(4444444448123), true}, 529 {"7fffffff", INT_MAX, true}, 530 {"-80000000", 0, false}, 531 {"ffffffff", 0xffffffff, true}, 532 {"DeadBeef", 0xdeadbeef, true}, 533 {"0x42", 66, true}, 534 {"-0x42", 0, false}, 535 {"+0x42", 66, true}, 536 {"0x40acd88557b", GG_INT64_C(4444444448123), true}, 537 {"0x7fffffff", INT_MAX, true}, 538 {"-0x80000000", 0, false}, 539 {"0xffffffff", 0xffffffff, true}, 540 {"0XDeadBeef", 0xdeadbeef, true}, 541 {"0x7fffffffffffffff", kint64max, true}, 542 {"-0x8000000000000000", 0, false}, 543 {"0x8000000000000000", GG_UINT64_C(0x8000000000000000), true}, 544 {"-0x8000000000000001", 0, false}, 545 {"0xFFFFFFFFFFFFFFFF", kuint64max, true}, 546 {"FFFFFFFFFFFFFFFF", kuint64max, true}, 547 {"0x0000000000000000", 0, true}, 548 {"0000000000000000", 0, true}, 549 {"1FFFFFFFFFFFFFFFF", kuint64max, false}, // Overflow test. 550 {"0x0f", 15, true}, 551 {"0f", 15, true}, 552 {" 45", 0x45, false}, 553 {"\t\n\v\f\r 0x45", 0x45, false}, 554 {" 45", 0x45, false}, 555 {"45 ", 0x45, false}, 556 {"45:", 0x45, false}, 557 {"efgh", 0xef, false}, 558 {"0xefgh", 0xef, false}, 559 {"hgfe", 0, false}, 560 {"-", 0, false}, 561 {"", 0, false}, 562 {"0x", 0, false}, 563 }; 564 565 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 566 uint64 output = 0; 567 EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output)); 568 EXPECT_EQ(cases[i].output, output); 569 } 570 // One additional test to verify that conversion of numbers in strings with 571 // embedded NUL characters. The NUL and extra data after it should be 572 // interpreted as junk after the number. 573 const char input[] = "0xc0ffee\09"; 574 std::string input_string(input, arraysize(input) - 1); 575 uint64 output; 576 EXPECT_FALSE(HexStringToUInt64(input_string, &output)); 577 EXPECT_EQ(0xc0ffeeU, output); 578 } 579 580 TEST(StringNumberConversionsTest, HexStringToBytes) { 581 static const struct { 582 const std::string input; 583 const char* output; 584 size_t output_len; 585 bool success; 586 } cases[] = { 587 {"0", "", 0, false}, // odd number of characters fails 588 {"00", "\0", 1, true}, 589 {"42", "\x42", 1, true}, 590 {"-42", "", 0, false}, // any non-hex value fails 591 {"+42", "", 0, false}, 592 {"7fffffff", "\x7f\xff\xff\xff", 4, true}, 593 {"80000000", "\x80\0\0\0", 4, true}, 594 {"deadbeef", "\xde\xad\xbe\xef", 4, true}, 595 {"DeadBeef", "\xde\xad\xbe\xef", 4, true}, 596 {"0x42", "", 0, false}, // leading 0x fails (x is not hex) 597 {"0f", "\xf", 1, true}, 598 {"45 ", "\x45", 1, false}, 599 {"efgh", "\xef", 1, false}, 600 {"", "", 0, false}, 601 {"0123456789ABCDEF", "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8, true}, 602 {"0123456789ABCDEF012345", 603 "\x01\x23\x45\x67\x89\xAB\xCD\xEF\x01\x23\x45", 11, true}, 604 }; 605 606 607 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 608 std::vector<uint8> output; 609 std::vector<uint8> compare; 610 EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) << 611 i << ": " << cases[i].input; 612 for (size_t j = 0; j < cases[i].output_len; ++j) 613 compare.push_back(static_cast<uint8>(cases[i].output[j])); 614 ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input; 615 EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) << 616 i << ": " << cases[i].input; 617 } 618 } 619 620 TEST(StringNumberConversionsTest, StringToDouble) { 621 static const struct { 622 std::string input; 623 double output; 624 bool success; 625 } cases[] = { 626 {"0", 0.0, true}, 627 {"42", 42.0, true}, 628 {"-42", -42.0, true}, 629 {"123.45", 123.45, true}, 630 {"-123.45", -123.45, true}, 631 {"+123.45", 123.45, true}, 632 {"2.99792458e8", 299792458.0, true}, 633 {"149597870.691E+3", 149597870691.0, true}, 634 {"6.", 6.0, true}, 635 {"9e99999999999999999999", HUGE_VAL, false}, 636 {"-9e99999999999999999999", -HUGE_VAL, false}, 637 {"1e-2", 0.01, true}, 638 {"42 ", 42.0, false}, 639 {" 1e-2", 0.01, false}, 640 {"1e-2 ", 0.01, false}, 641 {"-1E-7", -0.0000001, true}, 642 {"01e02", 100, true}, 643 {"2.3e15", 2.3e15, true}, 644 {"\t\n\v\f\r -123.45e2", -12345.0, false}, 645 {"+123 e4", 123.0, false}, 646 {"123e ", 123.0, false}, 647 {"123e", 123.0, false}, 648 {" 2.99", 2.99, false}, 649 {"1e3.4", 1000.0, false}, 650 {"nothing", 0.0, false}, 651 {"-", 0.0, false}, 652 {"+", 0.0, false}, 653 {"", 0.0, false}, 654 }; 655 656 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 657 double output; 658 errno = 1; 659 EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)); 660 if (cases[i].success) 661 EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged. 662 EXPECT_DOUBLE_EQ(cases[i].output, output); 663 } 664 665 // One additional test to verify that conversion of numbers in strings with 666 // embedded NUL characters. The NUL and extra data after it should be 667 // interpreted as junk after the number. 668 const char input[] = "3.14\0159"; 669 std::string input_string(input, arraysize(input) - 1); 670 double output; 671 EXPECT_FALSE(StringToDouble(input_string, &output)); 672 EXPECT_DOUBLE_EQ(3.14, output); 673 } 674 675 TEST(StringNumberConversionsTest, DoubleToString) { 676 static const struct { 677 double input; 678 const char* expected; 679 } cases[] = { 680 {0.0, "0"}, 681 {1.25, "1.25"}, 682 {1.33518e+012, "1.33518e+12"}, 683 {1.33489e+012, "1.33489e+12"}, 684 {1.33505e+012, "1.33505e+12"}, 685 {1.33545e+009, "1335450000"}, 686 {1.33503e+009, "1335030000"}, 687 }; 688 689 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 690 EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input)); 691 } 692 693 // The following two values were seen in crashes in the wild. 694 const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'}; 695 double input = 0; 696 memcpy(&input, input_bytes, arraysize(input_bytes)); 697 EXPECT_EQ("1335179083776", DoubleToString(input)); 698 const char input_bytes2[8] = 699 {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'}; 700 input = 0; 701 memcpy(&input, input_bytes2, arraysize(input_bytes2)); 702 EXPECT_EQ("1334890332160", DoubleToString(input)); 703 } 704 705 TEST(StringNumberConversionsTest, HexEncode) { 706 std::string hex(HexEncode(NULL, 0)); 707 EXPECT_EQ(hex.length(), 0U); 708 unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81}; 709 hex = HexEncode(bytes, sizeof(bytes)); 710 EXPECT_EQ(hex.compare("01FF02FE038081"), 0); 711 } 712 713 } // namespace base 714