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