string_number_conversions_unittest.cc 25 KB

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