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 "base/strings/string_number_conversions.h" 6 7 #include <errno.h> 8 #include <limits.h> 9 #include <stddef.h> 10 #include <stdint.h> 11 #include <stdio.h> 12 13 #include <cmath> 14 #include <limits> 15 16 #include "base/bit_cast.h" 17 #include "base/format_macros.h" 18 #include "base/macros.h" 19 #include "base/strings/stringprintf.h" 20 #include "base/strings/utf_string_conversions.h" 21 #include "testing/gtest/include/gtest/gtest.h" 22 23 namespace base { 24 25 namespace { 26 27 template <typename INT> 28 struct IntToStringTest { 29 INT num; 30 const char* sexpected; 31 const char* uexpected; 32 }; 33 34 } // namespace 35 36 TEST(StringNumberConversionsTest, IntToString) { 37 static const IntToStringTest<int> int_tests[] = { 38 { 0, "0", "0" }, 39 { -1, "-1", "4294967295" }, 40 { std::numeric_limits<int>::max(), "2147483647", "2147483647" }, 41 { std::numeric_limits<int>::min(), "-2147483648", "2147483648" }, 42 }; 43 static const IntToStringTest<int64_t> int64_tests[] = { 44 {0, "0", "0"}, 45 {-1, "-1", "18446744073709551615"}, 46 { 47 std::numeric_limits<int64_t>::max(), "9223372036854775807", 48 "9223372036854775807", 49 }, 50 {std::numeric_limits<int64_t>::min(), "-9223372036854775808", 51 "9223372036854775808"}, 52 }; 53 54 for (size_t i = 0; i < arraysize(int_tests); ++i) { 55 const IntToStringTest<int>* test = &int_tests[i]; 56 EXPECT_EQ(IntToString(test->num), test->sexpected); 57 EXPECT_EQ(IntToString16(test->num), UTF8ToUTF16(test->sexpected)); 58 EXPECT_EQ(UintToString(test->num), test->uexpected); 59 EXPECT_EQ(UintToString16(test->num), UTF8ToUTF16(test->uexpected)); 60 } 61 for (size_t i = 0; i < arraysize(int64_tests); ++i) { 62 const IntToStringTest<int64_t>* test = &int64_tests[i]; 63 EXPECT_EQ(Int64ToString(test->num), test->sexpected); 64 EXPECT_EQ(Int64ToString16(test->num), UTF8ToUTF16(test->sexpected)); 65 EXPECT_EQ(Uint64ToString(test->num), test->uexpected); 66 EXPECT_EQ(Uint64ToString16(test->num), UTF8ToUTF16(test->uexpected)); 67 } 68 } 69 70 TEST(StringNumberConversionsTest, Uint64ToString) { 71 static const struct { 72 uint64_t input; 73 std::string output; 74 } cases[] = { 75 {0, "0"}, 76 {42, "42"}, 77 {INT_MAX, "2147483647"}, 78 {std::numeric_limits<uint64_t>::max(), "18446744073709551615"}, 79 }; 80 81 for (size_t i = 0; i < arraysize(cases); ++i) 82 EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input)); 83 } 84 85 TEST(StringNumberConversionsTest, SizeTToString) { 86 size_t size_t_max = std::numeric_limits<size_t>::max(); 87 std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max); 88 89 static const struct { 90 size_t input; 91 std::string output; 92 } cases[] = { 93 {0, "0"}, 94 {9, "9"}, 95 {42, "42"}, 96 {INT_MAX, "2147483647"}, 97 {2147483648U, "2147483648"}, 98 #if SIZE_MAX > 4294967295U 99 {99999999999U, "99999999999"}, 100 #endif 101 {size_t_max, size_t_max_string}, 102 }; 103 104 for (size_t i = 0; i < arraysize(cases); ++i) 105 EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input)); 106 } 107 108 TEST(StringNumberConversionsTest, StringToInt) { 109 static const struct { 110 std::string input; 111 int output; 112 bool success; 113 } cases[] = { 114 {"0", 0, true}, 115 {"42", 42, true}, 116 {"42\x99", 42, false}, 117 {"\x99" "42\x99", 0, false}, 118 {"-2147483648", INT_MIN, true}, 119 {"2147483647", INT_MAX, true}, 120 {"", 0, false}, 121 {" 42", 42, false}, 122 {"42 ", 42, false}, 123 {"\t\n\v\f\r 42", 42, false}, 124 {"blah42", 0, false}, 125 {"42blah", 42, false}, 126 {"blah42blah", 0, false}, 127 {"-273.15", -273, false}, 128 {"+98.6", 98, false}, 129 {"--123", 0, false}, 130 {"++123", 0, false}, 131 {"-+123", 0, false}, 132 {"+-123", 0, false}, 133 {"-", 0, false}, 134 {"-2147483649", INT_MIN, false}, 135 {"-99999999999", INT_MIN, false}, 136 {"2147483648", INT_MAX, false}, 137 {"99999999999", INT_MAX, false}, 138 }; 139 140 for (size_t i = 0; i < arraysize(cases); ++i) { 141 int output = cases[i].output ^ 1; // Ensure StringToInt wrote something. 142 EXPECT_EQ(cases[i].success, StringToInt(cases[i].input, &output)); 143 EXPECT_EQ(cases[i].output, output); 144 145 string16 utf16_input = UTF8ToUTF16(cases[i].input); 146 output = cases[i].output ^ 1; // Ensure StringToInt wrote something. 147 EXPECT_EQ(cases[i].success, StringToInt(utf16_input, &output)); 148 EXPECT_EQ(cases[i].output, output); 149 } 150 151 // One additional test to verify that conversion of numbers in strings with 152 // embedded NUL characters. The NUL and extra data after it should be 153 // interpreted as junk after the number. 154 const char input[] = "6\06"; 155 std::string input_string(input, arraysize(input) - 1); 156 int output; 157 EXPECT_FALSE(StringToInt(input_string, &output)); 158 EXPECT_EQ(6, output); 159 160 string16 utf16_input = UTF8ToUTF16(input_string); 161 output = 0; 162 EXPECT_FALSE(StringToInt(utf16_input, &output)); 163 EXPECT_EQ(6, output); 164 165 output = 0; 166 const char16 negative_wide_input[] = { 0xFF4D, '4', '2', 0}; 167 EXPECT_FALSE(StringToInt(string16(negative_wide_input), &output)); 168 EXPECT_EQ(0, output); 169 } 170 171 TEST(StringNumberConversionsTest, StringToUint) { 172 static const struct { 173 std::string input; 174 unsigned output; 175 bool success; 176 } cases[] = { 177 {"0", 0, true}, 178 {"42", 42, true}, 179 {"42\x99", 42, false}, 180 {"\x99" "42\x99", 0, false}, 181 {"-2147483648", 0, false}, 182 {"2147483647", INT_MAX, true}, 183 {"", 0, false}, 184 {" 42", 42, false}, 185 {"42 ", 42, false}, 186 {"\t\n\v\f\r 42", 42, false}, 187 {"blah42", 0, false}, 188 {"42blah", 42, false}, 189 {"blah42blah", 0, false}, 190 {"-273.15", 0, false}, 191 {"+98.6", 98, false}, 192 {"--123", 0, false}, 193 {"++123", 0, false}, 194 {"-+123", 0, false}, 195 {"+-123", 0, false}, 196 {"-", 0, false}, 197 {"-2147483649", 0, false}, 198 {"-99999999999", 0, false}, 199 {"4294967295", UINT_MAX, true}, 200 {"4294967296", UINT_MAX, false}, 201 {"99999999999", UINT_MAX, false}, 202 }; 203 204 for (size_t i = 0; i < arraysize(cases); ++i) { 205 unsigned output = 206 cases[i].output ^ 1; // Ensure StringToUint wrote something. 207 EXPECT_EQ(cases[i].success, StringToUint(cases[i].input, &output)); 208 EXPECT_EQ(cases[i].output, output); 209 210 string16 utf16_input = UTF8ToUTF16(cases[i].input); 211 output = cases[i].output ^ 1; // Ensure StringToUint wrote something. 212 EXPECT_EQ(cases[i].success, StringToUint(utf16_input, &output)); 213 EXPECT_EQ(cases[i].output, output); 214 } 215 216 // One additional test to verify that conversion of numbers in strings with 217 // embedded NUL characters. The NUL and extra data after it should be 218 // interpreted as junk after the number. 219 const char input[] = "6\06"; 220 std::string input_string(input, arraysize(input) - 1); 221 unsigned output; 222 EXPECT_FALSE(StringToUint(input_string, &output)); 223 EXPECT_EQ(6U, output); 224 225 string16 utf16_input = UTF8ToUTF16(input_string); 226 output = 0; 227 EXPECT_FALSE(StringToUint(utf16_input, &output)); 228 EXPECT_EQ(6U, output); 229 230 output = 0; 231 const char16 negative_wide_input[] = { 0xFF4D, '4', '2', 0}; 232 EXPECT_FALSE(StringToUint(string16(negative_wide_input), &output)); 233 EXPECT_EQ(0U, output); 234 } 235 236 TEST(StringNumberConversionsTest, StringToInt64) { 237 static const struct { 238 std::string input; 239 int64_t output; 240 bool success; 241 } cases[] = { 242 {"0", 0, true}, 243 {"42", 42, true}, 244 {"-2147483648", INT_MIN, true}, 245 {"2147483647", INT_MAX, true}, 246 {"-2147483649", INT64_C(-2147483649), true}, 247 {"-99999999999", INT64_C(-99999999999), true}, 248 {"2147483648", INT64_C(2147483648), true}, 249 {"99999999999", INT64_C(99999999999), true}, 250 {"9223372036854775807", std::numeric_limits<int64_t>::max(), true}, 251 {"-9223372036854775808", std::numeric_limits<int64_t>::min(), true}, 252 {"09", 9, true}, 253 {"-09", -9, true}, 254 {"", 0, false}, 255 {" 42", 42, false}, 256 {"42 ", 42, false}, 257 {"0x42", 0, false}, 258 {"\t\n\v\f\r 42", 42, false}, 259 {"blah42", 0, false}, 260 {"42blah", 42, false}, 261 {"blah42blah", 0, false}, 262 {"-273.15", -273, false}, 263 {"+98.6", 98, false}, 264 {"--123", 0, false}, 265 {"++123", 0, false}, 266 {"-+123", 0, false}, 267 {"+-123", 0, false}, 268 {"-", 0, false}, 269 {"-9223372036854775809", std::numeric_limits<int64_t>::min(), false}, 270 {"-99999999999999999999", std::numeric_limits<int64_t>::min(), false}, 271 {"9223372036854775808", std::numeric_limits<int64_t>::max(), false}, 272 {"99999999999999999999", std::numeric_limits<int64_t>::max(), false}, 273 }; 274 275 for (size_t i = 0; i < arraysize(cases); ++i) { 276 int64_t output = 0; 277 EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output)); 278 EXPECT_EQ(cases[i].output, output); 279 280 string16 utf16_input = UTF8ToUTF16(cases[i].input); 281 output = 0; 282 EXPECT_EQ(cases[i].success, StringToInt64(utf16_input, &output)); 283 EXPECT_EQ(cases[i].output, output); 284 } 285 286 // One additional test to verify that conversion of numbers in strings with 287 // embedded NUL characters. The NUL and extra data after it should be 288 // interpreted as junk after the number. 289 const char input[] = "6\06"; 290 std::string input_string(input, arraysize(input) - 1); 291 int64_t output; 292 EXPECT_FALSE(StringToInt64(input_string, &output)); 293 EXPECT_EQ(6, output); 294 295 string16 utf16_input = UTF8ToUTF16(input_string); 296 output = 0; 297 EXPECT_FALSE(StringToInt64(utf16_input, &output)); 298 EXPECT_EQ(6, output); 299 } 300 301 TEST(StringNumberConversionsTest, StringToUint64) { 302 static const struct { 303 std::string input; 304 uint64_t output; 305 bool success; 306 } cases[] = { 307 {"0", 0, true}, 308 {"42", 42, true}, 309 {"-2147483648", 0, false}, 310 {"2147483647", INT_MAX, true}, 311 {"-2147483649", 0, false}, 312 {"-99999999999", 0, false}, 313 {"2147483648", UINT64_C(2147483648), true}, 314 {"99999999999", UINT64_C(99999999999), true}, 315 {"9223372036854775807", std::numeric_limits<int64_t>::max(), true}, 316 {"-9223372036854775808", 0, false}, 317 {"09", 9, true}, 318 {"-09", 0, false}, 319 {"", 0, false}, 320 {" 42", 42, false}, 321 {"42 ", 42, false}, 322 {"0x42", 0, false}, 323 {"\t\n\v\f\r 42", 42, false}, 324 {"blah42", 0, false}, 325 {"42blah", 42, false}, 326 {"blah42blah", 0, false}, 327 {"-273.15", 0, false}, 328 {"+98.6", 98, false}, 329 {"--123", 0, false}, 330 {"++123", 0, false}, 331 {"-+123", 0, false}, 332 {"+-123", 0, false}, 333 {"-", 0, false}, 334 {"-9223372036854775809", 0, false}, 335 {"-99999999999999999999", 0, false}, 336 {"9223372036854775808", UINT64_C(9223372036854775808), true}, 337 {"99999999999999999999", std::numeric_limits<uint64_t>::max(), false}, 338 {"18446744073709551615", std::numeric_limits<uint64_t>::max(), true}, 339 {"18446744073709551616", std::numeric_limits<uint64_t>::max(), false}, 340 }; 341 342 for (size_t i = 0; i < arraysize(cases); ++i) { 343 uint64_t output = 0; 344 EXPECT_EQ(cases[i].success, StringToUint64(cases[i].input, &output)); 345 EXPECT_EQ(cases[i].output, output); 346 347 string16 utf16_input = UTF8ToUTF16(cases[i].input); 348 output = 0; 349 EXPECT_EQ(cases[i].success, StringToUint64(utf16_input, &output)); 350 EXPECT_EQ(cases[i].output, output); 351 } 352 353 // One additional test to verify that conversion of numbers in strings with 354 // embedded NUL characters. The NUL and extra data after it should be 355 // interpreted as junk after the number. 356 const char input[] = "6\06"; 357 std::string input_string(input, arraysize(input) - 1); 358 uint64_t output; 359 EXPECT_FALSE(StringToUint64(input_string, &output)); 360 EXPECT_EQ(6U, output); 361 362 string16 utf16_input = UTF8ToUTF16(input_string); 363 output = 0; 364 EXPECT_FALSE(StringToUint64(utf16_input, &output)); 365 EXPECT_EQ(6U, output); 366 } 367 368 TEST(StringNumberConversionsTest, StringToSizeT) { 369 size_t size_t_max = std::numeric_limits<size_t>::max(); 370 std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max); 371 372 static const struct { 373 std::string input; 374 size_t output; 375 bool success; 376 } cases[] = { 377 {"0", 0, true}, 378 {"42", 42, true}, 379 {"-2147483648", 0, false}, 380 {"2147483647", INT_MAX, true}, 381 {"-2147483649", 0, false}, 382 {"-99999999999", 0, false}, 383 {"2147483648", 2147483648U, true}, 384 #if SIZE_MAX > 4294967295U 385 {"99999999999", 99999999999U, true}, 386 #endif 387 {"-9223372036854775808", 0, false}, 388 {"09", 9, true}, 389 {"-09", 0, false}, 390 {"", 0, false}, 391 {" 42", 42, false}, 392 {"42 ", 42, false}, 393 {"0x42", 0, false}, 394 {"\t\n\v\f\r 42", 42, false}, 395 {"blah42", 0, false}, 396 {"42blah", 42, false}, 397 {"blah42blah", 0, false}, 398 {"-273.15", 0, false}, 399 {"+98.6", 98, false}, 400 {"--123", 0, false}, 401 {"++123", 0, false}, 402 {"-+123", 0, false}, 403 {"+-123", 0, false}, 404 {"-", 0, false}, 405 {"-9223372036854775809", 0, false}, 406 {"-99999999999999999999", 0, false}, 407 {"999999999999999999999999", size_t_max, false}, 408 {size_t_max_string, size_t_max, true}, 409 }; 410 411 for (size_t i = 0; i < arraysize(cases); ++i) { 412 size_t output = 0; 413 EXPECT_EQ(cases[i].success, StringToSizeT(cases[i].input, &output)); 414 EXPECT_EQ(cases[i].output, output); 415 416 string16 utf16_input = UTF8ToUTF16(cases[i].input); 417 output = 0; 418 EXPECT_EQ(cases[i].success, StringToSizeT(utf16_input, &output)); 419 EXPECT_EQ(cases[i].output, output); 420 } 421 422 // One additional test to verify that conversion of numbers in strings with 423 // embedded NUL characters. The NUL and extra data after it should be 424 // interpreted as junk after the number. 425 const char input[] = "6\06"; 426 std::string input_string(input, arraysize(input) - 1); 427 size_t output; 428 EXPECT_FALSE(StringToSizeT(input_string, &output)); 429 EXPECT_EQ(6U, output); 430 431 string16 utf16_input = UTF8ToUTF16(input_string); 432 output = 0; 433 EXPECT_FALSE(StringToSizeT(utf16_input, &output)); 434 EXPECT_EQ(6U, output); 435 } 436 437 TEST(StringNumberConversionsTest, HexStringToInt) { 438 static const struct { 439 std::string input; 440 int64_t output; 441 bool success; 442 } cases[] = { 443 {"0", 0, true}, 444 {"42", 66, true}, 445 {"-42", -66, true}, 446 {"+42", 66, true}, 447 {"7fffffff", INT_MAX, true}, 448 {"-80000000", INT_MIN, true}, 449 {"80000000", INT_MAX, false}, // Overflow test. 450 {"-80000001", INT_MIN, false}, // Underflow test. 451 {"0x42", 66, true}, 452 {"-0x42", -66, true}, 453 {"+0x42", 66, true}, 454 {"0x7fffffff", INT_MAX, true}, 455 {"-0x80000000", INT_MIN, true}, 456 {"-80000000", INT_MIN, true}, 457 {"80000000", INT_MAX, false}, // Overflow test. 458 {"-80000001", INT_MIN, false}, // Underflow test. 459 {"0x0f", 15, true}, 460 {"0f", 15, true}, 461 {" 45", 0x45, false}, 462 {"\t\n\v\f\r 0x45", 0x45, false}, 463 {" 45", 0x45, false}, 464 {"45 ", 0x45, false}, 465 {"45:", 0x45, false}, 466 {"efgh", 0xef, false}, 467 {"0xefgh", 0xef, false}, 468 {"hgfe", 0, false}, 469 {"-", 0, false}, 470 {"", 0, false}, 471 {"0x", 0, false}, 472 }; 473 474 for (size_t i = 0; i < arraysize(cases); ++i) { 475 int output = 0; 476 EXPECT_EQ(cases[i].success, HexStringToInt(cases[i].input, &output)); 477 EXPECT_EQ(cases[i].output, output); 478 } 479 // One additional test to verify that conversion of numbers in strings with 480 // embedded NUL characters. The NUL and extra data after it should be 481 // interpreted as junk after the number. 482 const char input[] = "0xc0ffee\0" "9"; 483 std::string input_string(input, arraysize(input) - 1); 484 int output; 485 EXPECT_FALSE(HexStringToInt(input_string, &output)); 486 EXPECT_EQ(0xc0ffee, output); 487 } 488 489 TEST(StringNumberConversionsTest, HexStringToUInt) { 490 static const struct { 491 std::string input; 492 uint32_t output; 493 bool success; 494 } cases[] = { 495 {"0", 0, true}, 496 {"42", 0x42, true}, 497 {"-42", 0, false}, 498 {"+42", 0x42, true}, 499 {"7fffffff", INT_MAX, true}, 500 {"-80000000", 0, false}, 501 {"ffffffff", 0xffffffff, true}, 502 {"DeadBeef", 0xdeadbeef, true}, 503 {"0x42", 0x42, true}, 504 {"-0x42", 0, false}, 505 {"+0x42", 0x42, true}, 506 {"0x7fffffff", INT_MAX, true}, 507 {"-0x80000000", 0, false}, 508 {"0xffffffff", std::numeric_limits<uint32_t>::max(), true}, 509 {"0XDeadBeef", 0xdeadbeef, true}, 510 {"0x7fffffffffffffff", std::numeric_limits<uint32_t>::max(), 511 false}, // Overflow test. 512 {"-0x8000000000000000", 0, false}, 513 {"0x8000000000000000", std::numeric_limits<uint32_t>::max(), 514 false}, // Overflow test. 515 {"-0x8000000000000001", 0, false}, 516 {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(), 517 false}, // Overflow test. 518 {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(), 519 false}, // Overflow test. 520 {"0x0000000000000000", 0, true}, 521 {"0000000000000000", 0, true}, 522 {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(), 523 false}, // Overflow test. 524 {"0x0f", 0x0f, true}, 525 {"0f", 0x0f, true}, 526 {" 45", 0x45, false}, 527 {"\t\n\v\f\r 0x45", 0x45, false}, 528 {" 45", 0x45, false}, 529 {"45 ", 0x45, false}, 530 {"45:", 0x45, false}, 531 {"efgh", 0xef, false}, 532 {"0xefgh", 0xef, false}, 533 {"hgfe", 0, false}, 534 {"-", 0, false}, 535 {"", 0, false}, 536 {"0x", 0, false}, 537 }; 538 539 for (size_t i = 0; i < arraysize(cases); ++i) { 540 uint32_t output = 0; 541 EXPECT_EQ(cases[i].success, HexStringToUInt(cases[i].input, &output)); 542 EXPECT_EQ(cases[i].output, output); 543 } 544 // One additional test to verify that conversion of numbers in strings with 545 // embedded NUL characters. The NUL and extra data after it should be 546 // interpreted as junk after the number. 547 const char input[] = "0xc0ffee\0" "9"; 548 std::string input_string(input, arraysize(input) - 1); 549 uint32_t output; 550 EXPECT_FALSE(HexStringToUInt(input_string, &output)); 551 EXPECT_EQ(0xc0ffeeU, output); 552 } 553 554 TEST(StringNumberConversionsTest, HexStringToInt64) { 555 static const struct { 556 std::string input; 557 int64_t output; 558 bool success; 559 } cases[] = { 560 {"0", 0, true}, 561 {"42", 66, true}, 562 {"-42", -66, true}, 563 {"+42", 66, true}, 564 {"40acd88557b", INT64_C(4444444448123), true}, 565 {"7fffffff", INT_MAX, true}, 566 {"-80000000", INT_MIN, true}, 567 {"ffffffff", 0xffffffff, true}, 568 {"DeadBeef", 0xdeadbeef, true}, 569 {"0x42", 66, true}, 570 {"-0x42", -66, true}, 571 {"+0x42", 66, true}, 572 {"0x40acd88557b", INT64_C(4444444448123), true}, 573 {"0x7fffffff", INT_MAX, true}, 574 {"-0x80000000", INT_MIN, true}, 575 {"0xffffffff", 0xffffffff, true}, 576 {"0XDeadBeef", 0xdeadbeef, true}, 577 {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true}, 578 {"-0x8000000000000000", std::numeric_limits<int64_t>::min(), true}, 579 {"0x8000000000000000", std::numeric_limits<int64_t>::max(), 580 false}, // Overflow test. 581 {"-0x8000000000000001", std::numeric_limits<int64_t>::min(), 582 false}, // Underflow test. 583 {"0x0f", 15, true}, 584 {"0f", 15, true}, 585 {" 45", 0x45, false}, 586 {"\t\n\v\f\r 0x45", 0x45, false}, 587 {" 45", 0x45, false}, 588 {"45 ", 0x45, false}, 589 {"45:", 0x45, false}, 590 {"efgh", 0xef, false}, 591 {"0xefgh", 0xef, false}, 592 {"hgfe", 0, false}, 593 {"-", 0, false}, 594 {"", 0, false}, 595 {"0x", 0, false}, 596 }; 597 598 for (size_t i = 0; i < arraysize(cases); ++i) { 599 int64_t output = 0; 600 EXPECT_EQ(cases[i].success, HexStringToInt64(cases[i].input, &output)); 601 EXPECT_EQ(cases[i].output, output); 602 } 603 // One additional test to verify that conversion of numbers in strings with 604 // embedded NUL characters. The NUL and extra data after it should be 605 // interpreted as junk after the number. 606 const char input[] = "0xc0ffee\0" "9"; 607 std::string input_string(input, arraysize(input) - 1); 608 int64_t output; 609 EXPECT_FALSE(HexStringToInt64(input_string, &output)); 610 EXPECT_EQ(0xc0ffee, output); 611 } 612 613 TEST(StringNumberConversionsTest, HexStringToUInt64) { 614 static const struct { 615 std::string input; 616 uint64_t output; 617 bool success; 618 } cases[] = { 619 {"0", 0, true}, 620 {"42", 66, true}, 621 {"-42", 0, false}, 622 {"+42", 66, true}, 623 {"40acd88557b", INT64_C(4444444448123), true}, 624 {"7fffffff", INT_MAX, true}, 625 {"-80000000", 0, false}, 626 {"ffffffff", 0xffffffff, true}, 627 {"DeadBeef", 0xdeadbeef, true}, 628 {"0x42", 66, true}, 629 {"-0x42", 0, false}, 630 {"+0x42", 66, true}, 631 {"0x40acd88557b", INT64_C(4444444448123), true}, 632 {"0x7fffffff", INT_MAX, true}, 633 {"-0x80000000", 0, false}, 634 {"0xffffffff", 0xffffffff, true}, 635 {"0XDeadBeef", 0xdeadbeef, true}, 636 {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true}, 637 {"-0x8000000000000000", 0, false}, 638 {"0x8000000000000000", UINT64_C(0x8000000000000000), true}, 639 {"-0x8000000000000001", 0, false}, 640 {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true}, 641 {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true}, 642 {"0x0000000000000000", 0, true}, 643 {"0000000000000000", 0, true}, 644 {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), 645 false}, // Overflow test. 646 {"0x0f", 15, true}, 647 {"0f", 15, true}, 648 {" 45", 0x45, false}, 649 {"\t\n\v\f\r 0x45", 0x45, false}, 650 {" 45", 0x45, false}, 651 {"45 ", 0x45, false}, 652 {"45:", 0x45, false}, 653 {"efgh", 0xef, false}, 654 {"0xefgh", 0xef, false}, 655 {"hgfe", 0, false}, 656 {"-", 0, false}, 657 {"", 0, false}, 658 {"0x", 0, false}, 659 }; 660 661 for (size_t i = 0; i < arraysize(cases); ++i) { 662 uint64_t output = 0; 663 EXPECT_EQ(cases[i].success, HexStringToUInt64(cases[i].input, &output)); 664 EXPECT_EQ(cases[i].output, output); 665 } 666 // One additional test to verify that conversion of numbers in strings with 667 // embedded NUL characters. The NUL and extra data after it should be 668 // interpreted as junk after the number. 669 const char input[] = "0xc0ffee\0" "9"; 670 std::string input_string(input, arraysize(input) - 1); 671 uint64_t output; 672 EXPECT_FALSE(HexStringToUInt64(input_string, &output)); 673 EXPECT_EQ(0xc0ffeeU, output); 674 } 675 676 TEST(StringNumberConversionsTest, HexStringToBytes) { 677 static const struct { 678 const std::string input; 679 const char* output; 680 size_t output_len; 681 bool success; 682 } cases[] = { 683 {"0", "", 0, false}, // odd number of characters fails 684 {"00", "\0", 1, true}, 685 {"42", "\x42", 1, true}, 686 {"-42", "", 0, false}, // any non-hex value fails 687 {"+42", "", 0, false}, 688 {"7fffffff", "\x7f\xff\xff\xff", 4, true}, 689 {"80000000", "\x80\0\0\0", 4, true}, 690 {"deadbeef", "\xde\xad\xbe\xef", 4, true}, 691 {"DeadBeef", "\xde\xad\xbe\xef", 4, true}, 692 {"0x42", "", 0, false}, // leading 0x fails (x is not hex) 693 {"0f", "\xf", 1, true}, 694 {"45 ", "\x45", 1, false}, 695 {"efgh", "\xef", 1, false}, 696 {"", "", 0, false}, 697 {"0123456789ABCDEF", "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8, true}, 698 {"0123456789ABCDEF012345", 699 "\x01\x23\x45\x67\x89\xAB\xCD\xEF\x01\x23\x45", 11, true}, 700 }; 701 702 703 for (size_t i = 0; i < arraysize(cases); ++i) { 704 std::vector<uint8_t> output; 705 std::vector<uint8_t> compare; 706 EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) << 707 i << ": " << cases[i].input; 708 for (size_t j = 0; j < cases[i].output_len; ++j) 709 compare.push_back(static_cast<uint8_t>(cases[i].output[j])); 710 ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input; 711 EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) << 712 i << ": " << cases[i].input; 713 } 714 } 715 716 TEST(StringNumberConversionsTest, StringToDouble) { 717 static const struct { 718 std::string input; 719 double output; 720 bool success; 721 } cases[] = { 722 {"0", 0.0, true}, 723 {"42", 42.0, true}, 724 {"-42", -42.0, true}, 725 {"123.45", 123.45, true}, 726 {"-123.45", -123.45, true}, 727 {"+123.45", 123.45, true}, 728 {"2.99792458e8", 299792458.0, true}, 729 {"149597870.691E+3", 149597870691.0, true}, 730 {"6.", 6.0, true}, 731 {"9e99999999999999999999", std::numeric_limits<double>::infinity(), 732 false}, 733 {"-9e99999999999999999999", -std::numeric_limits<double>::infinity(), 734 false}, 735 {"1e-2", 0.01, true}, 736 {"42 ", 42.0, false}, 737 {" 1e-2", 0.01, false}, 738 {"1e-2 ", 0.01, false}, 739 {"-1E-7", -0.0000001, true}, 740 {"01e02", 100, true}, 741 {"2.3e15", 2.3e15, true}, 742 {"\t\n\v\f\r -123.45e2", -12345.0, false}, 743 {"+123 e4", 123.0, false}, 744 {"123e ", 123.0, false}, 745 {"123e", 123.0, false}, 746 {" 2.99", 2.99, false}, 747 {"1e3.4", 1000.0, false}, 748 {"nothing", 0.0, false}, 749 {"-", 0.0, false}, 750 {"+", 0.0, false}, 751 {"", 0.0, false}, 752 }; 753 754 for (size_t i = 0; i < arraysize(cases); ++i) { 755 double output; 756 errno = 1; 757 EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)) 758 << "for input=" << cases[i].input << "got output=" << output; 759 if (cases[i].success) 760 EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged. 761 EXPECT_DOUBLE_EQ(cases[i].output, output); 762 } 763 764 // One additional test to verify that conversion of numbers in strings with 765 // embedded NUL characters. The NUL and extra data after it should be 766 // interpreted as junk after the number. 767 const char input[] = "3.14\0" "159"; 768 std::string input_string(input, arraysize(input) - 1); 769 double output; 770 EXPECT_FALSE(StringToDouble(input_string, &output)); 771 EXPECT_DOUBLE_EQ(3.14, output); 772 } 773 774 TEST(StringNumberConversionsTest, DoubleToString) { 775 static const struct { 776 double input; 777 const char* expected; 778 } cases[] = { 779 {0.0, "0.0"}, 780 {1.25, "1.25"}, 781 {1.33518e+012, "1335180000000.0"}, 782 {1.33489e+012, "1334890000000.0"}, 783 {1.33505e+012, "1335050000000.0"}, 784 {1.33545e+009, "1335450000.0"}, 785 {1.33503e+009, "1335030000.0"}, 786 }; 787 788 for (size_t i = 0; i < arraysize(cases); ++i) { 789 EXPECT_EQ(cases[i].expected, DoubleToString(cases[i].input)); 790 } 791 792 // The following two values were seen in crashes in the wild. 793 const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'}; 794 double input = 0; 795 memcpy(&input, input_bytes, arraysize(input_bytes)); 796 EXPECT_EQ("1335179083776.0", DoubleToString(input)); 797 const char input_bytes2[8] = 798 {0, 0, 0, '\xa0', '\xda', '\x6c', '\x73', '\x42'}; 799 input = 0; 800 memcpy(&input, input_bytes2, arraysize(input_bytes2)); 801 EXPECT_EQ("1334890332160.0", DoubleToString(input)); 802 } 803 804 TEST(StringNumberConversionsTest, HexEncode) { 805 std::string hex(HexEncode(NULL, 0)); 806 EXPECT_EQ(hex.length(), 0U); 807 unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81}; 808 hex = HexEncode(bytes, sizeof(bytes)); 809 EXPECT_EQ(hex.compare("01FF02FE038081"), 0); 810 } 811 812 } // namespace base 813