1 // Copyright (c) 2010 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 <math.h> 6 7 #include <limits> 8 9 #include "base/string_number_conversions.h" 10 #include "base/utf_string_conversions.h" 11 #include "testing/gtest/include/gtest/gtest.h" 12 13 namespace base { 14 15 namespace { 16 17 template <typename INT> 18 struct IntToStringTest { 19 INT num; 20 const char* sexpected; 21 const char* uexpected; 22 }; 23 24 } // namespace 25 26 TEST(StringNumberConversionsTest, IntToString) { 27 static const IntToStringTest<int> int_tests[] = { 28 { 0, "0", "0" }, 29 { -1, "-1", "4294967295" }, 30 { std::numeric_limits<int>::max(), "2147483647", "2147483647" }, 31 { std::numeric_limits<int>::min(), "-2147483648", "2147483648" }, 32 }; 33 static const IntToStringTest<int64> int64_tests[] = { 34 { 0, "0", "0" }, 35 { -1, "-1", "18446744073709551615" }, 36 { std::numeric_limits<int64>::max(), 37 "9223372036854775807", 38 "9223372036854775807", }, 39 { std::numeric_limits<int64>::min(), 40 "-9223372036854775808", 41 "9223372036854775808" }, 42 }; 43 44 for (size_t i = 0; i < arraysize(int_tests); ++i) { 45 const IntToStringTest<int>* test = &int_tests[i]; 46 EXPECT_EQ(IntToString(test->num), test->sexpected); 47 EXPECT_EQ(IntToString16(test->num), UTF8ToUTF16(test->sexpected)); 48 EXPECT_EQ(UintToString(test->num), test->uexpected); 49 EXPECT_EQ(UintToString16(test->num), UTF8ToUTF16(test->uexpected)); 50 } 51 for (size_t i = 0; i < arraysize(int64_tests); ++i) { 52 const IntToStringTest<int64>* test = &int64_tests[i]; 53 EXPECT_EQ(Int64ToString(test->num), test->sexpected); 54 EXPECT_EQ(Int64ToString16(test->num), UTF8ToUTF16(test->sexpected)); 55 EXPECT_EQ(Uint64ToString(test->num), test->uexpected); 56 EXPECT_EQ(Uint64ToString16(test->num), UTF8ToUTF16(test->uexpected)); 57 } 58 } 59 60 TEST(StringNumberConversionsTest, Uint64ToString) { 61 static const struct { 62 uint64 input; 63 std::string output; 64 } cases[] = { 65 {0, "0"}, 66 {42, "42"}, 67 {INT_MAX, "2147483647"}, 68 {kuint64max, "18446744073709551615"}, 69 }; 70 71 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) 72 EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input)); 73 } 74 75 TEST(StringNumberConversionsTest, StringToInt) { 76 static const struct { 77 std::string input; 78 int output; 79 bool success; 80 } cases[] = { 81 {"0", 0, true}, 82 {"42", 42, true}, 83 {"42\x99", 42, false}, 84 {"\x99" "42\x99", 0, false}, 85 {"-2147483648", INT_MIN, true}, 86 {"2147483647", INT_MAX, true}, 87 {"", 0, false}, 88 {" 42", 42, false}, 89 {"42 ", 42, false}, 90 {"\t\n\v\f\r 42", 42, false}, 91 {"blah42", 0, false}, 92 {"42blah", 42, false}, 93 {"blah42blah", 0, false}, 94 {"-273.15", -273, false}, 95 {"+98.6", 98, false}, 96 {"--123", 0, false}, 97 {"++123", 0, false}, 98 {"-+123", 0, false}, 99 {"+-123", 0, false}, 100 {"-", 0, false}, 101 {"-2147483649", INT_MIN, false}, 102 {"-99999999999", INT_MIN, false}, 103 {"2147483648", INT_MAX, false}, 104 {"99999999999", INT_MAX, false}, 105 }; 106 107 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 108 const char* ascii_chars = cases[i].input.c_str(); 109 int output = 0; 110 EXPECT_EQ(cases[i].success, StringToInt(cases[i].input, &output)); 111 EXPECT_EQ(cases[i].output, output); 112 output = 0; 113 EXPECT_EQ(cases[i].success, StringToInt(cases[i].input.begin(), 114 cases[i].input.end(), 115 &output)); 116 EXPECT_EQ(cases[i].output, output); 117 output = 0; 118 EXPECT_EQ(cases[i].success, StringToInt( 119 ascii_chars, ascii_chars + cases[i].input.length(), &output)); 120 EXPECT_EQ(cases[i].output, output); 121 122 string16 utf16_input = UTF8ToUTF16(cases[i].input); 123 const char16* utf16_chars = utf16_input.c_str(); 124 output = 0; 125 EXPECT_EQ(cases[i].success, StringToInt(utf16_input, &output)); 126 EXPECT_EQ(cases[i].output, output); 127 output = 0; 128 EXPECT_EQ(cases[i].success, StringToInt(utf16_input.begin(), 129 utf16_input.end(), 130 &output)); 131 EXPECT_EQ(cases[i].output, output); 132 output = 0; 133 EXPECT_EQ(cases[i].success, StringToInt( 134 utf16_chars, utf16_chars + utf16_input.length(), &output)); 135 EXPECT_EQ(cases[i].output, output); 136 } 137 138 // One additional test to verify that conversion of numbers in strings with 139 // embedded NUL characters. The NUL and extra data after it should be 140 // interpreted as junk after the number. 141 const char input[] = "6\06"; 142 std::string input_string(input, arraysize(input) - 1); 143 int output; 144 EXPECT_FALSE(StringToInt(input_string, &output)); 145 EXPECT_EQ(6, output); 146 output = 0; 147 EXPECT_FALSE(StringToInt(input_string.begin(), input_string.end(), &output)); 148 EXPECT_EQ(6, output); 149 output = 0; 150 EXPECT_FALSE(StringToInt(input, input + arraysize(input), &output)); 151 EXPECT_EQ(6, output); 152 153 string16 utf16_input = UTF8ToUTF16(input_string); 154 const char16* utf16_chars = utf16_input.c_str(); 155 output = 0; 156 EXPECT_FALSE(StringToInt(utf16_input, &output)); 157 EXPECT_EQ(6, output); 158 output = 0; 159 EXPECT_FALSE(StringToInt(utf16_input.begin(), utf16_input.end(), &output)); 160 EXPECT_EQ(6, output); 161 output = 0; 162 EXPECT_FALSE(StringToInt(utf16_chars, 163 utf16_chars + utf16_input.length(), 164 &output)); 165 EXPECT_EQ(6, output); 166 167 output = 0; 168 const char16 negative_wide_input[] = { 0xFF4D, '4', '2', 0}; 169 EXPECT_FALSE(StringToInt(string16(negative_wide_input), &output)); 170 EXPECT_EQ(0, output); 171 } 172 173 TEST(StringNumberConversionsTest, StringToInt64) { 174 static const struct { 175 std::string input; 176 int64 output; 177 bool success; 178 } cases[] = { 179 {"0", 0, true}, 180 {"42", 42, true}, 181 {"-2147483648", INT_MIN, true}, 182 {"2147483647", INT_MAX, true}, 183 {"-2147483649", GG_INT64_C(-2147483649), true}, 184 {"-99999999999", GG_INT64_C(-99999999999), true}, 185 {"2147483648", GG_INT64_C(2147483648), true}, 186 {"99999999999", GG_INT64_C(99999999999), true}, 187 {"9223372036854775807", kint64max, true}, 188 {"-9223372036854775808", kint64min, true}, 189 {"09", 9, true}, 190 {"-09", -9, true}, 191 {"", 0, false}, 192 {" 42", 42, false}, 193 {"42 ", 42, false}, 194 {"0x42", 0, false}, 195 {"\t\n\v\f\r 42", 42, false}, 196 {"blah42", 0, false}, 197 {"42blah", 42, false}, 198 {"blah42blah", 0, false}, 199 {"-273.15", -273, false}, 200 {"+98.6", 98, false}, 201 {"--123", 0, false}, 202 {"++123", 0, false}, 203 {"-+123", 0, false}, 204 {"+-123", 0, false}, 205 {"-", 0, false}, 206 {"-9223372036854775809", kint64min, false}, 207 {"-99999999999999999999", kint64min, false}, 208 {"9223372036854775808", kint64max, false}, 209 {"99999999999999999999", kint64max, false}, 210 }; 211 212 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 213 const char* ascii_chars = cases[i].input.c_str(); 214 int64 output = 0; 215 EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output)); 216 EXPECT_EQ(cases[i].output, output); 217 output = 0; 218 EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input.begin(), 219 cases[i].input.end(), 220 &output)); 221 EXPECT_EQ(cases[i].output, output); 222 output = 0; 223 EXPECT_EQ(cases[i].success, StringToInt64( 224 ascii_chars, ascii_chars + cases[i].input.length(), &output)); 225 EXPECT_EQ(cases[i].output, output); 226 227 string16 utf16_input = UTF8ToUTF16(cases[i].input); 228 const char16* utf16_chars = utf16_input.c_str(); 229 output = 0; 230 EXPECT_EQ(cases[i].success, StringToInt64(utf16_input, &output)); 231 EXPECT_EQ(cases[i].output, output); 232 output = 0; 233 EXPECT_EQ(cases[i].success, StringToInt64(utf16_input.begin(), 234 utf16_input.end(), 235 &output)); 236 EXPECT_EQ(cases[i].output, output); 237 output = 0; 238 EXPECT_EQ(cases[i].success, StringToInt64( 239 utf16_chars, utf16_chars + utf16_input.length(), &output)); 240 EXPECT_EQ(cases[i].output, output); 241 } 242 243 // One additional test to verify that conversion of numbers in strings with 244 // embedded NUL characters. The NUL and extra data after it should be 245 // interpreted as junk after the number. 246 const char input[] = "6\06"; 247 std::string input_string(input, arraysize(input) - 1); 248 int64 output; 249 EXPECT_FALSE(StringToInt64(input_string, &output)); 250 EXPECT_EQ(6, output); 251 output = 0; 252 EXPECT_FALSE(StringToInt64(input_string.begin(), 253 input_string.end(), 254 &output)); 255 EXPECT_EQ(6, output); 256 output = 0; 257 EXPECT_FALSE(StringToInt64(input, input + arraysize(input), &output)); 258 EXPECT_EQ(6, output); 259 260 string16 utf16_input = UTF8ToUTF16(input_string); 261 const char16* utf16_chars = utf16_input.c_str(); 262 output = 0; 263 EXPECT_FALSE(StringToInt64(utf16_input, &output)); 264 EXPECT_EQ(6, output); 265 output = 0; 266 EXPECT_FALSE(StringToInt64(utf16_input.begin(), utf16_input.end(), &output)); 267 EXPECT_EQ(6, output); 268 output = 0; 269 EXPECT_FALSE(StringToInt64(utf16_chars, 270 utf16_chars + utf16_input.length(), 271 &output)); 272 EXPECT_EQ(6, output); 273 } 274 275 TEST(StringNumberConversionsTest, HexStringToInt) { 276 static const struct { 277 std::string input; 278 int output; 279 bool success; 280 } cases[] = { 281 {"0", 0, true}, 282 {"42", 66, true}, 283 {"-42", -66, true}, 284 {"+42", 66, true}, 285 {"7fffffff", INT_MAX, true}, 286 {"80000000", INT_MIN, true}, 287 {"ffffffff", -1, true}, 288 {"DeadBeef", 0xdeadbeef, true}, 289 {"0x42", 66, true}, 290 {"-0x42", -66, true}, 291 {"+0x42", 66, true}, 292 {"0x7fffffff", INT_MAX, true}, 293 {"0x80000000", INT_MIN, true}, 294 {"0xffffffff", -1, true}, 295 {"0XDeadBeef", 0xdeadbeef, true}, 296 {"0x0f", 15, true}, 297 {"0f", 15, true}, 298 {" 45", 0x45, false}, 299 {"\t\n\v\f\r 0x45", 0x45, false}, 300 {" 45", 0x45, false}, 301 {"45 ", 0x45, false}, 302 {"45:", 0x45, false}, 303 {"efgh", 0xef, false}, 304 {"0xefgh", 0xef, false}, 305 {"hgfe", 0, false}, 306 {"100000000", -1, false}, // don't care about |output|, just |success| 307 {"-", 0, false}, 308 {"", 0, false}, 309 }; 310 311 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 312 const char* ascii_chars = cases[i].input.c_str(); 313 int output = 0; 314 EXPECT_EQ(cases[i].success, HexStringToInt(cases[i].input, &output)); 315 EXPECT_EQ(cases[i].output, output); 316 output = 0; 317 EXPECT_EQ(cases[i].success, HexStringToInt(cases[i].input.begin(), 318 cases[i].input.end(), 319 &output)); 320 EXPECT_EQ(cases[i].output, output); 321 output = 0; 322 EXPECT_EQ(cases[i].success, HexStringToInt( 323 ascii_chars, ascii_chars + cases[i].input.length(), &output)); 324 EXPECT_EQ(cases[i].output, output); 325 } 326 // One additional test to verify that conversion of numbers in strings with 327 // embedded NUL characters. The NUL and extra data after it should be 328 // interpreted as junk after the number. 329 const char input[] = "0xc0ffee\09"; 330 std::string input_string(input, arraysize(input) - 1); 331 int output; 332 EXPECT_FALSE(HexStringToInt(input_string, &output)); 333 EXPECT_EQ(0xc0ffee, output); 334 output = 0; 335 EXPECT_FALSE(HexStringToInt(input_string.begin(), 336 input_string.end(), 337 &output)); 338 EXPECT_EQ(0xc0ffee, output); 339 output = 0; 340 EXPECT_FALSE(HexStringToInt(input, input + arraysize(input), &output)); 341 EXPECT_EQ(0xc0ffee, output); 342 } 343 344 TEST(StringNumberConversionsTest, HexStringToBytes) { 345 static const struct { 346 const std::string input; 347 const char* output; 348 size_t output_len; 349 bool success; 350 } cases[] = { 351 {"0", "", 0, false}, // odd number of characters fails 352 {"00", "\0", 1, true}, 353 {"42", "\x42", 1, true}, 354 {"-42", "", 0, false}, // any non-hex value fails 355 {"+42", "", 0, false}, 356 {"7fffffff", "\x7f\xff\xff\xff", 4, true}, 357 {"80000000", "\x80\0\0\0", 4, true}, 358 {"deadbeef", "\xde\xad\xbe\xef", 4, true}, 359 {"DeadBeef", "\xde\xad\xbe\xef", 4, true}, 360 {"0x42", "", 0, false}, // leading 0x fails (x is not hex) 361 {"0f", "\xf", 1, true}, 362 {"45 ", "\x45", 1, false}, 363 {"efgh", "\xef", 1, false}, 364 {"", "", 0, false}, 365 {"0123456789ABCDEF", "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8, true}, 366 {"0123456789ABCDEF012345", 367 "\x01\x23\x45\x67\x89\xAB\xCD\xEF\x01\x23\x45", 11, true}, 368 }; 369 370 371 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 372 std::vector<uint8> output; 373 std::vector<uint8> compare; 374 EXPECT_EQ(cases[i].success, HexStringToBytes(cases[i].input, &output)) << 375 i << ": " << cases[i].input; 376 for (size_t j = 0; j < cases[i].output_len; ++j) 377 compare.push_back(static_cast<uint8>(cases[i].output[j])); 378 ASSERT_EQ(output.size(), compare.size()) << i << ": " << cases[i].input; 379 EXPECT_TRUE(std::equal(output.begin(), output.end(), compare.begin())) << 380 i << ": " << cases[i].input; 381 } 382 } 383 384 TEST(StringNumberConversionsTest, StringToDouble) { 385 static const struct { 386 std::string input; 387 double output; 388 bool success; 389 } cases[] = { 390 {"0", 0.0, true}, 391 {"42", 42.0, true}, 392 {"-42", -42.0, true}, 393 {"123.45", 123.45, true}, 394 {"-123.45", -123.45, true}, 395 {"+123.45", 123.45, true}, 396 {"2.99792458e8", 299792458.0, true}, 397 {"149597870.691E+3", 149597870691.0, true}, 398 {"6.", 6.0, true}, 399 {"9e99999999999999999999", HUGE_VAL, false}, 400 {"-9e99999999999999999999", -HUGE_VAL, false}, 401 {"1e-2", 0.01, true}, 402 {"42 ", 42.0, false}, 403 {" 1e-2", 0.01, false}, 404 {"1e-2 ", 0.01, false}, 405 {"-1E-7", -0.0000001, true}, 406 {"01e02", 100, true}, 407 {"2.3e15", 2.3e15, true}, 408 {"\t\n\v\f\r -123.45e2", -12345.0, false}, 409 {"+123 e4", 123.0, false}, 410 {"123e ", 123.0, false}, 411 {"123e", 123.0, false}, 412 {" 2.99", 2.99, false}, 413 {"1e3.4", 1000.0, false}, 414 {"nothing", 0.0, false}, 415 {"-", 0.0, false}, 416 {"+", 0.0, false}, 417 {"", 0.0, false}, 418 }; 419 420 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { 421 double output; 422 EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)); 423 EXPECT_DOUBLE_EQ(cases[i].output, output); 424 } 425 426 // One additional test to verify that conversion of numbers in strings with 427 // embedded NUL characters. The NUL and extra data after it should be 428 // interpreted as junk after the number. 429 const char input[] = "3.14\0159"; 430 std::string input_string(input, arraysize(input) - 1); 431 double output; 432 EXPECT_FALSE(StringToDouble(input_string, &output)); 433 EXPECT_DOUBLE_EQ(3.14, output); 434 } 435 436 TEST(StringNumberConversionsTest, HexEncode) { 437 std::string hex(HexEncode(NULL, 0)); 438 EXPECT_EQ(hex.length(), 0U); 439 unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81}; 440 hex = HexEncode(bytes, sizeof(bytes)); 441 EXPECT_EQ(hex.compare("01FF02FE038081"), 0); 442 } 443 444 } // namespace base 445