string_number_conversions_unittest.cc 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981
  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 "base/strings/string_number_conversions.h"
  5. #include <errno.h>
  6. #include <limits.h>
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <stdio.h>
  10. #include <cmath>
  11. #include <limits>
  12. #include "base/bit_cast.h"
  13. #include "base/format_macros.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "base/strings/utf_string_conversions.h"
  16. #include "testing/gtest/include/gtest/gtest.h"
  17. namespace base {
  18. namespace {
  19. template <typename INT>
  20. struct NumberToStringTest {
  21. INT num;
  22. const char* sexpected;
  23. const char* uexpected;
  24. };
  25. } // namespace
  26. TEST(StringNumberConversionsTest, NumberToString) {
  27. static const NumberToStringTest<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 NumberToStringTest<int64_t> int64_tests[] = {
  34. {0, "0", "0"},
  35. {-1, "-1", "18446744073709551615"},
  36. {
  37. std::numeric_limits<int64_t>::max(),
  38. "9223372036854775807",
  39. "9223372036854775807",
  40. },
  41. {std::numeric_limits<int64_t>::min(), "-9223372036854775808",
  42. "9223372036854775808"},
  43. };
  44. for (const auto& test : int_tests) {
  45. EXPECT_EQ(NumberToString(test.num), test.sexpected);
  46. EXPECT_EQ(NumberToString16(test.num), UTF8ToUTF16(test.sexpected));
  47. EXPECT_EQ(NumberToString(static_cast<unsigned>(test.num)), test.uexpected);
  48. EXPECT_EQ(NumberToString16(static_cast<unsigned>(test.num)),
  49. UTF8ToUTF16(test.uexpected));
  50. }
  51. for (const auto& test : int64_tests) {
  52. EXPECT_EQ(NumberToString(test.num), test.sexpected);
  53. EXPECT_EQ(NumberToString16(test.num), UTF8ToUTF16(test.sexpected));
  54. EXPECT_EQ(NumberToString(static_cast<uint64_t>(test.num)), test.uexpected);
  55. EXPECT_EQ(NumberToString16(static_cast<uint64_t>(test.num)),
  56. UTF8ToUTF16(test.uexpected));
  57. }
  58. }
  59. TEST(StringNumberConversionsTest, Uint64ToString) {
  60. static const struct {
  61. uint64_t input;
  62. std::string output;
  63. } cases[] = {
  64. {0, "0"},
  65. {42, "42"},
  66. {INT_MAX, "2147483647"},
  67. {std::numeric_limits<uint64_t>::max(), "18446744073709551615"},
  68. };
  69. for (const auto& i : cases)
  70. EXPECT_EQ(i.output, NumberToString(i.input));
  71. }
  72. TEST(StringNumberConversionsTest, SizeTToString) {
  73. size_t size_t_max = std::numeric_limits<size_t>::max();
  74. std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max);
  75. static const struct {
  76. size_t input;
  77. std::string output;
  78. } cases[] = {
  79. {0, "0"},
  80. {9, "9"},
  81. {42, "42"},
  82. {INT_MAX, "2147483647"},
  83. {2147483648U, "2147483648"},
  84. #if SIZE_MAX > 4294967295U
  85. {99999999999U, "99999999999"},
  86. #endif
  87. {size_t_max, size_t_max_string},
  88. };
  89. for (const auto& i : cases)
  90. EXPECT_EQ(i.output, NumberToString(i.input));
  91. }
  92. TEST(StringNumberConversionsTest, StringToInt) {
  93. static const struct {
  94. std::string input;
  95. int output;
  96. bool success;
  97. } cases[] = {
  98. {"0", 0, true},
  99. {"42", 42, true},
  100. {"42\x99", 42, false},
  101. {"\x99"
  102. "42\x99",
  103. 0, false},
  104. {"-2147483648", INT_MIN, true},
  105. {"2147483647", INT_MAX, true},
  106. {"", 0, false},
  107. {" 42", 42, false},
  108. {"42 ", 42, false},
  109. {"\t\n\v\f\r 42", 42, false},
  110. {"blah42", 0, false},
  111. {"42blah", 42, false},
  112. {"blah42blah", 0, false},
  113. {"-273.15", -273, false},
  114. {"+98.6", 98, false},
  115. {"--123", 0, false},
  116. {"++123", 0, false},
  117. {"-+123", 0, false},
  118. {"+-123", 0, false},
  119. {"-", 0, false},
  120. {"-2147483649", INT_MIN, false},
  121. {"-99999999999", INT_MIN, false},
  122. {"2147483648", INT_MAX, false},
  123. {"99999999999", INT_MAX, false},
  124. };
  125. for (const auto& i : cases) {
  126. int output = i.output ^ 1; // Ensure StringToInt wrote something.
  127. EXPECT_EQ(i.success, StringToInt(i.input, &output));
  128. EXPECT_EQ(i.output, output);
  129. std::u16string utf16_input = UTF8ToUTF16(i.input);
  130. output = i.output ^ 1; // Ensure StringToInt wrote something.
  131. EXPECT_EQ(i.success, StringToInt(utf16_input, &output));
  132. EXPECT_EQ(i.output, output);
  133. }
  134. // One additional test to verify that conversion of numbers in strings with
  135. // embedded NUL characters. The NUL and extra data after it should be
  136. // interpreted as junk after the number.
  137. const char input[] =
  138. "6\0"
  139. "6";
  140. std::string input_string(input, std::size(input) - 1);
  141. int output;
  142. EXPECT_FALSE(StringToInt(input_string, &output));
  143. EXPECT_EQ(6, output);
  144. std::u16string utf16_input = UTF8ToUTF16(input_string);
  145. output = 0;
  146. EXPECT_FALSE(StringToInt(utf16_input, &output));
  147. EXPECT_EQ(6, output);
  148. output = 0;
  149. const char16_t negative_wide_input[] = {0xFF4D, '4', '2', 0};
  150. EXPECT_FALSE(StringToInt(std::u16string(negative_wide_input), &output));
  151. EXPECT_EQ(0, output);
  152. }
  153. TEST(StringNumberConversionsTest, StringToUint) {
  154. static const struct {
  155. std::string input;
  156. unsigned output;
  157. bool success;
  158. } cases[] = {
  159. {"0", 0, true},
  160. {"42", 42, true},
  161. {"42\x99", 42, false},
  162. {"\x99"
  163. "42\x99",
  164. 0, false},
  165. {"-2147483648", 0, false},
  166. {"2147483647", INT_MAX, true},
  167. {"", 0, false},
  168. {" 42", 42, false},
  169. {"42 ", 42, false},
  170. {"\t\n\v\f\r 42", 42, false},
  171. {"blah42", 0, false},
  172. {"42blah", 42, false},
  173. {"blah42blah", 0, false},
  174. {"-273.15", 0, false},
  175. {"+98.6", 98, false},
  176. {"--123", 0, false},
  177. {"++123", 0, false},
  178. {"-+123", 0, false},
  179. {"+-123", 0, false},
  180. {"-", 0, false},
  181. {"-2147483649", 0, false},
  182. {"-99999999999", 0, false},
  183. {"4294967295", UINT_MAX, true},
  184. {"4294967296", UINT_MAX, false},
  185. {"99999999999", UINT_MAX, false},
  186. };
  187. for (const auto& i : cases) {
  188. unsigned output = i.output ^ 1; // Ensure StringToUint wrote something.
  189. EXPECT_EQ(i.success, StringToUint(i.input, &output));
  190. EXPECT_EQ(i.output, output);
  191. std::u16string utf16_input = UTF8ToUTF16(i.input);
  192. output = i.output ^ 1; // Ensure StringToUint wrote something.
  193. EXPECT_EQ(i.success, StringToUint(utf16_input, &output));
  194. EXPECT_EQ(i.output, output);
  195. }
  196. // One additional test to verify that conversion of numbers in strings with
  197. // embedded NUL characters. The NUL and extra data after it should be
  198. // interpreted as junk after the number.
  199. const char input[] =
  200. "6\0"
  201. "6";
  202. std::string input_string(input, std::size(input) - 1);
  203. unsigned output;
  204. EXPECT_FALSE(StringToUint(input_string, &output));
  205. EXPECT_EQ(6U, output);
  206. std::u16string utf16_input = UTF8ToUTF16(input_string);
  207. output = 0;
  208. EXPECT_FALSE(StringToUint(utf16_input, &output));
  209. EXPECT_EQ(6U, output);
  210. output = 0;
  211. const char16_t negative_wide_input[] = {0xFF4D, '4', '2', 0};
  212. EXPECT_FALSE(StringToUint(std::u16string(negative_wide_input), &output));
  213. EXPECT_EQ(0U, output);
  214. }
  215. TEST(StringNumberConversionsTest, StringToInt64) {
  216. static const struct {
  217. std::string input;
  218. int64_t output;
  219. bool success;
  220. } cases[] = {
  221. {"0", 0, true},
  222. {"42", 42, true},
  223. {"-2147483648", INT_MIN, true},
  224. {"2147483647", INT_MAX, true},
  225. {"-2147483649", INT64_C(-2147483649), true},
  226. {"-99999999999", INT64_C(-99999999999), true},
  227. {"2147483648", INT64_C(2147483648), true},
  228. {"99999999999", INT64_C(99999999999), true},
  229. {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
  230. {"-9223372036854775808", std::numeric_limits<int64_t>::min(), true},
  231. {"09", 9, true},
  232. {"-09", -9, true},
  233. {"", 0, false},
  234. {" 42", 42, false},
  235. {"42 ", 42, false},
  236. {"0x42", 0, false},
  237. {"\t\n\v\f\r 42", 42, false},
  238. {"blah42", 0, false},
  239. {"42blah", 42, false},
  240. {"blah42blah", 0, false},
  241. {"-273.15", -273, false},
  242. {"+98.6", 98, false},
  243. {"--123", 0, false},
  244. {"++123", 0, false},
  245. {"-+123", 0, false},
  246. {"+-123", 0, false},
  247. {"-", 0, false},
  248. {"-9223372036854775809", std::numeric_limits<int64_t>::min(), false},
  249. {"-99999999999999999999", std::numeric_limits<int64_t>::min(), false},
  250. {"9223372036854775808", std::numeric_limits<int64_t>::max(), false},
  251. {"99999999999999999999", std::numeric_limits<int64_t>::max(), false},
  252. };
  253. for (const auto& i : cases) {
  254. int64_t output = 0;
  255. EXPECT_EQ(i.success, StringToInt64(i.input, &output));
  256. EXPECT_EQ(i.output, output);
  257. std::u16string utf16_input = UTF8ToUTF16(i.input);
  258. output = 0;
  259. EXPECT_EQ(i.success, StringToInt64(utf16_input, &output));
  260. EXPECT_EQ(i.output, output);
  261. }
  262. // One additional test to verify that conversion of numbers in strings with
  263. // embedded NUL characters. The NUL and extra data after it should be
  264. // interpreted as junk after the number.
  265. const char input[] =
  266. "6\0"
  267. "6";
  268. std::string input_string(input, std::size(input) - 1);
  269. int64_t output;
  270. EXPECT_FALSE(StringToInt64(input_string, &output));
  271. EXPECT_EQ(6, output);
  272. std::u16string utf16_input = UTF8ToUTF16(input_string);
  273. output = 0;
  274. EXPECT_FALSE(StringToInt64(utf16_input, &output));
  275. EXPECT_EQ(6, output);
  276. }
  277. TEST(StringNumberConversionsTest, StringToUint64) {
  278. static const struct {
  279. std::string input;
  280. uint64_t output;
  281. bool success;
  282. } cases[] = {
  283. {"0", 0, true},
  284. {"42", 42, true},
  285. {"-2147483648", 0, false},
  286. {"2147483647", INT_MAX, true},
  287. {"-2147483649", 0, false},
  288. {"-99999999999", 0, false},
  289. {"2147483648", UINT64_C(2147483648), true},
  290. {"99999999999", UINT64_C(99999999999), true},
  291. {"9223372036854775807", std::numeric_limits<int64_t>::max(), true},
  292. {"-9223372036854775808", 0, false},
  293. {"09", 9, true},
  294. {"-09", 0, false},
  295. {"", 0, false},
  296. {" 42", 42, false},
  297. {"42 ", 42, false},
  298. {"0x42", 0, false},
  299. {"\t\n\v\f\r 42", 42, false},
  300. {"blah42", 0, false},
  301. {"42blah", 42, false},
  302. {"blah42blah", 0, false},
  303. {"-273.15", 0, false},
  304. {"+98.6", 98, false},
  305. {"--123", 0, false},
  306. {"++123", 0, false},
  307. {"-+123", 0, false},
  308. {"+-123", 0, false},
  309. {"-", 0, false},
  310. {"-9223372036854775809", 0, false},
  311. {"-99999999999999999999", 0, false},
  312. {"9223372036854775808", UINT64_C(9223372036854775808), true},
  313. {"99999999999999999999", std::numeric_limits<uint64_t>::max(), false},
  314. {"18446744073709551615", std::numeric_limits<uint64_t>::max(), true},
  315. {"18446744073709551616", std::numeric_limits<uint64_t>::max(), false},
  316. };
  317. for (const auto& i : cases) {
  318. uint64_t output = 0;
  319. EXPECT_EQ(i.success, StringToUint64(i.input, &output));
  320. EXPECT_EQ(i.output, output);
  321. std::u16string utf16_input = UTF8ToUTF16(i.input);
  322. output = 0;
  323. EXPECT_EQ(i.success, StringToUint64(utf16_input, &output));
  324. EXPECT_EQ(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[] =
  330. "6\0"
  331. "6";
  332. std::string input_string(input, std::size(input) - 1);
  333. uint64_t output;
  334. EXPECT_FALSE(StringToUint64(input_string, &output));
  335. EXPECT_EQ(6U, output);
  336. std::u16string utf16_input = UTF8ToUTF16(input_string);
  337. output = 0;
  338. EXPECT_FALSE(StringToUint64(utf16_input, &output));
  339. EXPECT_EQ(6U, output);
  340. }
  341. TEST(StringNumberConversionsTest, StringToSizeT) {
  342. size_t size_t_max = std::numeric_limits<size_t>::max();
  343. std::string size_t_max_string = StringPrintf("%" PRIuS, size_t_max);
  344. static const struct {
  345. std::string input;
  346. size_t output;
  347. bool success;
  348. } cases[] = {
  349. {"0", 0, true},
  350. {"42", 42, true},
  351. {"-2147483648", 0, false},
  352. {"2147483647", INT_MAX, true},
  353. {"-2147483649", 0, false},
  354. {"-99999999999", 0, false},
  355. {"2147483648", 2147483648U, true},
  356. #if SIZE_MAX > 4294967295U
  357. {"99999999999", 99999999999U, true},
  358. #endif
  359. {"-9223372036854775808", 0, false},
  360. {"09", 9, true},
  361. {"-09", 0, false},
  362. {"", 0, false},
  363. {" 42", 42, false},
  364. {"42 ", 42, false},
  365. {"0x42", 0, false},
  366. {"\t\n\v\f\r 42", 42, false},
  367. {"blah42", 0, false},
  368. {"42blah", 42, false},
  369. {"blah42blah", 0, false},
  370. {"-273.15", 0, false},
  371. {"+98.6", 98, false},
  372. {"--123", 0, false},
  373. {"++123", 0, false},
  374. {"-+123", 0, false},
  375. {"+-123", 0, false},
  376. {"-", 0, false},
  377. {"-9223372036854775809", 0, false},
  378. {"-99999999999999999999", 0, false},
  379. {"999999999999999999999999", size_t_max, false},
  380. {size_t_max_string, size_t_max, true},
  381. };
  382. for (const auto& i : cases) {
  383. size_t output = 0;
  384. EXPECT_EQ(i.success, StringToSizeT(i.input, &output));
  385. EXPECT_EQ(i.output, output);
  386. std::u16string utf16_input = UTF8ToUTF16(i.input);
  387. output = 0;
  388. EXPECT_EQ(i.success, StringToSizeT(utf16_input, &output));
  389. EXPECT_EQ(i.output, output);
  390. }
  391. // One additional test to verify that conversion of numbers in strings with
  392. // embedded NUL characters. The NUL and extra data after it should be
  393. // interpreted as junk after the number.
  394. const char input[] =
  395. "6\0"
  396. "6";
  397. std::string input_string(input, std::size(input) - 1);
  398. size_t output;
  399. EXPECT_FALSE(StringToSizeT(input_string, &output));
  400. EXPECT_EQ(6U, output);
  401. std::u16string utf16_input = UTF8ToUTF16(input_string);
  402. output = 0;
  403. EXPECT_FALSE(StringToSizeT(utf16_input, &output));
  404. EXPECT_EQ(6U, output);
  405. }
  406. TEST(StringNumberConversionsTest, HexStringToInt) {
  407. static const struct {
  408. std::string input;
  409. int64_t output;
  410. bool success;
  411. } cases[] = {
  412. {"0", 0, true},
  413. {"42", 66, true},
  414. {"-42", -66, true},
  415. {"+42", 66, true},
  416. {"7fffffff", INT_MAX, true},
  417. {"-80000000", INT_MIN, true},
  418. {"80000000", INT_MAX, false}, // Overflow test.
  419. {"-80000001", INT_MIN, false}, // Underflow test.
  420. {"0x42", 66, true},
  421. {"-0x42", -66, true},
  422. {"+0x42", 66, true},
  423. {"0x7fffffff", INT_MAX, true},
  424. {"-0x80000000", INT_MIN, true},
  425. {"-80000000", INT_MIN, true},
  426. {"80000000", INT_MAX, false}, // Overflow test.
  427. {"-80000001", INT_MIN, false}, // Underflow test.
  428. {"0x0f", 15, true},
  429. {"0f", 15, true},
  430. {" 45", 0x45, false},
  431. {"\t\n\v\f\r 0x45", 0x45, false},
  432. {" 45", 0x45, false},
  433. {"45 ", 0x45, false},
  434. {"45:", 0x45, false},
  435. {"efgh", 0xef, false},
  436. {"0xefgh", 0xef, false},
  437. {"hgfe", 0, false},
  438. {"-", 0, false},
  439. {"", 0, false},
  440. {"0x", 0, false},
  441. };
  442. for (const auto& i : cases) {
  443. int output = 0;
  444. EXPECT_EQ(i.success, HexStringToInt(i.input, &output));
  445. EXPECT_EQ(i.output, output);
  446. }
  447. // One additional test to verify that conversion of numbers in strings with
  448. // embedded NUL characters. The NUL and extra data after it should be
  449. // interpreted as junk after the number.
  450. const char input[] =
  451. "0xc0ffee\0"
  452. "9";
  453. std::string input_string(input, std::size(input) - 1);
  454. int output;
  455. EXPECT_FALSE(HexStringToInt(input_string, &output));
  456. EXPECT_EQ(0xc0ffee, output);
  457. }
  458. TEST(StringNumberConversionsTest, HexStringToUInt) {
  459. static const struct {
  460. std::string input;
  461. uint32_t output;
  462. bool success;
  463. } cases[] = {
  464. {"0", 0, true},
  465. {"42", 0x42, true},
  466. {"-42", 0, false},
  467. {"+42", 0x42, true},
  468. {"7fffffff", INT_MAX, true},
  469. {"-80000000", 0, false},
  470. {"ffffffff", 0xffffffff, true},
  471. {"DeadBeef", 0xdeadbeef, true},
  472. {"0x42", 0x42, true},
  473. {"-0x42", 0, false},
  474. {"+0x42", 0x42, true},
  475. {"0x7fffffff", INT_MAX, true},
  476. {"-0x80000000", 0, false},
  477. {"0xffffffff", std::numeric_limits<uint32_t>::max(), true},
  478. {"0XDeadBeef", 0xdeadbeef, true},
  479. {"0x7fffffffffffffff", std::numeric_limits<uint32_t>::max(),
  480. false}, // Overflow test.
  481. {"-0x8000000000000000", 0, false},
  482. {"0x8000000000000000", std::numeric_limits<uint32_t>::max(),
  483. false}, // Overflow test.
  484. {"-0x8000000000000001", 0, false},
  485. {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
  486. false}, // Overflow test.
  487. {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
  488. false}, // Overflow test.
  489. {"0x0000000000000000", 0, true},
  490. {"0000000000000000", 0, true},
  491. {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint32_t>::max(),
  492. false}, // Overflow test.
  493. {"0x0f", 0x0f, true},
  494. {"0f", 0x0f, true},
  495. {" 45", 0x45, false},
  496. {"\t\n\v\f\r 0x45", 0x45, false},
  497. {" 45", 0x45, false},
  498. {"45 ", 0x45, false},
  499. {"45:", 0x45, false},
  500. {"efgh", 0xef, false},
  501. {"0xefgh", 0xef, false},
  502. {"hgfe", 0, false},
  503. {"-", 0, false},
  504. {"", 0, false},
  505. {"0x", 0, false},
  506. };
  507. for (const auto& i : cases) {
  508. uint32_t output = 0;
  509. EXPECT_EQ(i.success, HexStringToUInt(i.input, &output));
  510. EXPECT_EQ(i.output, output);
  511. }
  512. // One additional test to verify that conversion of numbers in strings with
  513. // embedded NUL characters. The NUL and extra data after it should be
  514. // interpreted as junk after the number.
  515. const char input[] =
  516. "0xc0ffee\0"
  517. "9";
  518. std::string input_string(input, std::size(input) - 1);
  519. uint32_t output;
  520. EXPECT_FALSE(HexStringToUInt(input_string, &output));
  521. EXPECT_EQ(0xc0ffeeU, output);
  522. }
  523. TEST(StringNumberConversionsTest, HexStringToInt64) {
  524. static const struct {
  525. std::string input;
  526. int64_t output;
  527. bool success;
  528. } cases[] = {
  529. {"0", 0, true},
  530. {"42", 66, true},
  531. {"-42", -66, true},
  532. {"+42", 66, true},
  533. {"40acd88557b", INT64_C(4444444448123), true},
  534. {"7fffffff", INT_MAX, true},
  535. {"-80000000", INT_MIN, true},
  536. {"ffffffff", 0xffffffff, true},
  537. {"DeadBeef", 0xdeadbeef, true},
  538. {"0x42", 66, true},
  539. {"-0x42", -66, true},
  540. {"+0x42", 66, true},
  541. {"0x40acd88557b", INT64_C(4444444448123), true},
  542. {"0x7fffffff", INT_MAX, true},
  543. {"-0x80000000", INT_MIN, true},
  544. {"0xffffffff", 0xffffffff, true},
  545. {"0XDeadBeef", 0xdeadbeef, true},
  546. {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true},
  547. {"-0x8000000000000000", std::numeric_limits<int64_t>::min(), true},
  548. {"0x8000000000000000", std::numeric_limits<int64_t>::max(),
  549. false}, // Overflow test.
  550. {"-0x8000000000000001", std::numeric_limits<int64_t>::min(),
  551. false}, // Underflow test.
  552. {"0x0f", 15, true},
  553. {"0f", 15, true},
  554. {" 45", 0x45, false},
  555. {"\t\n\v\f\r 0x45", 0x45, false},
  556. {" 45", 0x45, false},
  557. {"45 ", 0x45, false},
  558. {"45:", 0x45, false},
  559. {"efgh", 0xef, false},
  560. {"0xefgh", 0xef, false},
  561. {"hgfe", 0, false},
  562. {"-", 0, false},
  563. {"", 0, false},
  564. {"0x", 0, false},
  565. };
  566. for (const auto& i : cases) {
  567. int64_t output = 0;
  568. EXPECT_EQ(i.success, HexStringToInt64(i.input, &output));
  569. EXPECT_EQ(i.output, output);
  570. }
  571. // One additional test to verify that conversion of numbers in strings with
  572. // embedded NUL characters. The NUL and extra data after it should be
  573. // interpreted as junk after the number.
  574. const char input[] =
  575. "0xc0ffee\0"
  576. "9";
  577. std::string input_string(input, std::size(input) - 1);
  578. int64_t output;
  579. EXPECT_FALSE(HexStringToInt64(input_string, &output));
  580. EXPECT_EQ(0xc0ffee, output);
  581. }
  582. TEST(StringNumberConversionsTest, HexStringToUInt64) {
  583. static const struct {
  584. std::string input;
  585. uint64_t output;
  586. bool success;
  587. } cases[] = {
  588. {"0", 0, true},
  589. {"42", 66, true},
  590. {"-42", 0, false},
  591. {"+42", 66, true},
  592. {"40acd88557b", INT64_C(4444444448123), true},
  593. {"7fffffff", INT_MAX, true},
  594. {"-80000000", 0, false},
  595. {"ffffffff", 0xffffffff, true},
  596. {"DeadBeef", 0xdeadbeef, true},
  597. {"0x42", 66, true},
  598. {"-0x42", 0, false},
  599. {"+0x42", 66, true},
  600. {"0x40acd88557b", INT64_C(4444444448123), true},
  601. {"0x7fffffff", INT_MAX, true},
  602. {"-0x80000000", 0, false},
  603. {"0xffffffff", 0xffffffff, true},
  604. {"0XDeadBeef", 0xdeadbeef, true},
  605. {"0x7fffffffffffffff", std::numeric_limits<int64_t>::max(), true},
  606. {"-0x8000000000000000", 0, false},
  607. {"0x8000000000000000", UINT64_C(0x8000000000000000), true},
  608. {"-0x8000000000000001", 0, false},
  609. {"0xFFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true},
  610. {"FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(), true},
  611. {"0x0000000000000000", 0, true},
  612. {"0000000000000000", 0, true},
  613. {"1FFFFFFFFFFFFFFFF", std::numeric_limits<uint64_t>::max(),
  614. false}, // Overflow test.
  615. {"0x0f", 15, true},
  616. {"0f", 15, true},
  617. {" 45", 0x45, false},
  618. {"\t\n\v\f\r 0x45", 0x45, false},
  619. {" 45", 0x45, false},
  620. {"45 ", 0x45, false},
  621. {"45:", 0x45, false},
  622. {"efgh", 0xef, false},
  623. {"0xefgh", 0xef, false},
  624. {"hgfe", 0, false},
  625. {"-", 0, false},
  626. {"", 0, false},
  627. {"0x", 0, false},
  628. };
  629. for (const auto& i : cases) {
  630. uint64_t output = 0;
  631. EXPECT_EQ(i.success, HexStringToUInt64(i.input, &output));
  632. EXPECT_EQ(i.output, output);
  633. }
  634. // One additional test to verify that conversion of numbers in strings with
  635. // embedded NUL characters. The NUL and extra data after it should be
  636. // interpreted as junk after the number.
  637. const char input[] =
  638. "0xc0ffee\0"
  639. "9";
  640. std::string input_string(input, std::size(input) - 1);
  641. uint64_t output;
  642. EXPECT_FALSE(HexStringToUInt64(input_string, &output));
  643. EXPECT_EQ(0xc0ffeeU, output);
  644. }
  645. // Tests for HexStringToBytes, HexStringToString, HexStringToSpan.
  646. TEST(StringNumberConversionsTest, HexStringToBytesStringSpan) {
  647. static const struct {
  648. const std::string input;
  649. const char* output;
  650. size_t output_len;
  651. bool success;
  652. } cases[] = {
  653. {"0", "", 0, false}, // odd number of characters fails
  654. {"00", "\0", 1, true},
  655. {"42", "\x42", 1, true},
  656. {"-42", "", 0, false}, // any non-hex value fails
  657. {"+42", "", 0, false},
  658. {"7fffffff", "\x7f\xff\xff\xff", 4, true},
  659. {"80000000", "\x80\0\0\0", 4, true},
  660. {"deadbeef", "\xde\xad\xbe\xef", 4, true},
  661. {"DeadBeef", "\xde\xad\xbe\xef", 4, true},
  662. {"0x42", "", 0, false}, // leading 0x fails (x is not hex)
  663. {"0f", "\xf", 1, true},
  664. {"45 ", "\x45", 1, false},
  665. {"efgh", "\xef", 1, false},
  666. {"", "", 0, false},
  667. {"0123456789ABCDEF", "\x01\x23\x45\x67\x89\xAB\xCD\xEF", 8, true},
  668. {"0123456789ABCDEF012345", "\x01\x23\x45\x67\x89\xAB\xCD\xEF\x01\x23\x45",
  669. 11, true},
  670. };
  671. for (size_t test_i = 0; test_i < std::size(cases); ++test_i) {
  672. const auto& test = cases[test_i];
  673. std::string expected_output(test.output, test.output_len);
  674. // Test HexStringToBytes().
  675. {
  676. std::vector<uint8_t> output;
  677. EXPECT_EQ(test.success, HexStringToBytes(test.input, &output))
  678. << test_i << ": " << test.input;
  679. EXPECT_EQ(expected_output, std::string(output.begin(), output.end()));
  680. }
  681. // Test HexStringToString().
  682. {
  683. std::string output;
  684. EXPECT_EQ(test.success, HexStringToString(test.input, &output))
  685. << test_i << ": " << test.input;
  686. EXPECT_EQ(expected_output, output) << test_i << ": " << test.input;
  687. }
  688. // Test HexStringToSpan() with a properly sized output.
  689. {
  690. std::vector<uint8_t> output;
  691. output.resize(test.input.size() / 2);
  692. EXPECT_EQ(test.success, HexStringToSpan(test.input, output))
  693. << test_i << ": " << test.input;
  694. // On failure the output will only have been partially written (with
  695. // everything after the failure being 0).
  696. for (size_t i = 0; i < test.output_len; ++i) {
  697. EXPECT_EQ(test.output[i], static_cast<char>(output[i]))
  698. << test_i << ": " << test.input;
  699. }
  700. for (size_t i = test.output_len; i < output.size(); ++i) {
  701. EXPECT_EQ('\0', static_cast<char>(output[i]))
  702. << test_i << ": " << test.input;
  703. }
  704. }
  705. // Test HexStringToSpan() with an output that is 1 byte too small.
  706. {
  707. std::vector<uint8_t> output;
  708. if (test.input.size() > 1)
  709. output.resize(test.input.size() / 2 - 1);
  710. EXPECT_FALSE(HexStringToSpan(test.input, output))
  711. << test_i << ": " << test.input;
  712. }
  713. // Test HexStringToSpan() with an output that is 1 byte too large.
  714. {
  715. std::vector<uint8_t> output;
  716. output.resize(test.input.size() / 2 + 1);
  717. EXPECT_FALSE(HexStringToSpan(test.input, output))
  718. << test_i << ": " << test.input;
  719. }
  720. }
  721. }
  722. TEST(StringNumberConversionsTest, StringToDouble) {
  723. static const struct {
  724. std::string input;
  725. double output;
  726. bool success;
  727. } cases[] = {
  728. // Test different forms of zero.
  729. {"0", 0.0, true},
  730. {"+0", 0.0, true},
  731. {"-0", 0.0, true},
  732. {"0.0", 0.0, true},
  733. {"000000000000000000000000000000.0", 0.0, true},
  734. {"0.000000000000000000000000000", 0.0, true},
  735. // Test the answer.
  736. {"42", 42.0, true},
  737. {"-42", -42.0, true},
  738. // Test variances of an ordinary number.
  739. {"123.45", 123.45, true},
  740. {"-123.45", -123.45, true},
  741. {"+123.45", 123.45, true},
  742. // Test different forms of representation.
  743. {"2.99792458e8", 299792458.0, true},
  744. {"149597870.691E+3", 149597870691.0, true},
  745. {"6.", 6.0, true},
  746. // Test around the largest/smallest value that a double can represent.
  747. {"9e307", 9e307, true},
  748. {"1.7976e308", 1.7976e308, true},
  749. {"1.7977e308", HUGE_VAL, false},
  750. {"1.797693134862315807e+308", HUGE_VAL, true},
  751. {"1.797693134862315808e+308", HUGE_VAL, false},
  752. {"9e308", HUGE_VAL, false},
  753. {"9e309", HUGE_VAL, false},
  754. {"9e999", HUGE_VAL, false},
  755. {"9e1999", HUGE_VAL, false},
  756. {"9e19999", HUGE_VAL, false},
  757. {"9e99999999999999999999", HUGE_VAL, false},
  758. {"-9e307", -9e307, true},
  759. {"-1.7976e308", -1.7976e308, true},
  760. {"-1.7977e308", -HUGE_VAL, false},
  761. {"-1.797693134862315807e+308", -HUGE_VAL, true},
  762. {"-1.797693134862315808e+308", -HUGE_VAL, false},
  763. {"-9e308", -HUGE_VAL, false},
  764. {"-9e309", -HUGE_VAL, false},
  765. {"-9e999", -HUGE_VAL, false},
  766. {"-9e1999", -HUGE_VAL, false},
  767. {"-9e19999", -HUGE_VAL, false},
  768. {"-9e99999999999999999999", -HUGE_VAL, false},
  769. // Test more exponents.
  770. {"1e-2", 0.01, true},
  771. {"42 ", 42.0, false},
  772. {" 1e-2", 0.01, false},
  773. {"1e-2 ", 0.01, false},
  774. {"-1E-7", -0.0000001, true},
  775. {"01e02", 100, true},
  776. {"2.3e15", 2.3e15, true},
  777. {"100e-309", 100e-309, true},
  778. // Test some invalid cases.
  779. {"\t\n\v\f\r -123.45e2", -12345.0, false},
  780. {"+123 e4", 123.0, false},
  781. {"123e ", 123.0, false},
  782. {"123e", 123.0, false},
  783. {"10.5px", 10.5, false},
  784. {"11.5e2em", 1150, false},
  785. {" 2.99", 2.99, false},
  786. {"1e3.4", 1000.0, false},
  787. {"nothing", 0.0, false},
  788. {"-", 0.0, false},
  789. {"+", 0.0, false},
  790. {"", 0.0, false},
  791. // crbug.org/588726
  792. {"-0.0010000000000000000000000000000000000000001e-256",
  793. -1.0000000000000001e-259, true},
  794. };
  795. for (size_t i = 0; i < std::size(cases); ++i) {
  796. SCOPED_TRACE(
  797. StringPrintf("case %" PRIuS " \"%s\"", i, cases[i].input.c_str()));
  798. double output;
  799. errno = 1;
  800. EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output));
  801. if (cases[i].success)
  802. EXPECT_EQ(1, errno) << i; // confirm that errno is unchanged.
  803. EXPECT_DOUBLE_EQ(cases[i].output, output);
  804. }
  805. // One additional test to verify that conversion of numbers in strings with
  806. // embedded NUL characters. The NUL and extra data after it should be
  807. // interpreted as junk after the number.
  808. const char input[] =
  809. "3.14\0"
  810. "159";
  811. std::string input_string(input, std::size(input) - 1);
  812. double output;
  813. EXPECT_FALSE(StringToDouble(input_string, &output));
  814. EXPECT_DOUBLE_EQ(3.14, output);
  815. }
  816. TEST(StringNumberConversionsTest, DoubleToString) {
  817. static const struct {
  818. double input;
  819. const char* expected;
  820. } cases[] = {
  821. {0.0, "0"},
  822. {0.5, "0.5"},
  823. {1.25, "1.25"},
  824. {1.33518e+012, "1.33518e+12"},
  825. {1.33489e+012, "1.33489e+12"},
  826. {1.33505e+012, "1.33505e+12"},
  827. {1.33545e+009, "1335450000"},
  828. {1.33503e+009, "1335030000"},
  829. };
  830. for (const auto& i : cases) {
  831. EXPECT_EQ(i.expected, NumberToString(i.input));
  832. EXPECT_EQ(i.expected, UTF16ToUTF8(NumberToString16(i.input)));
  833. }
  834. // The following two values were seen in crashes in the wild.
  835. const char input_bytes[8] = {0, 0, 0, 0, '\xee', '\x6d', '\x73', '\x42'};
  836. double input = 0;
  837. memcpy(&input, input_bytes, std::size(input_bytes));
  838. EXPECT_EQ("1.335179083776e+12", NumberToString(input));
  839. const char input_bytes2[8] = {0, 0, 0, '\xa0',
  840. '\xda', '\x6c', '\x73', '\x42'};
  841. input = 0;
  842. memcpy(&input, input_bytes2, std::size(input_bytes2));
  843. EXPECT_EQ("1.33489033216e+12", NumberToString(input));
  844. }
  845. TEST(StringNumberConversionsTest, HexEncode) {
  846. std::string hex(HexEncode(nullptr, 0));
  847. EXPECT_EQ(hex.length(), 0U);
  848. unsigned char bytes[] = {0x01, 0xff, 0x02, 0xfe, 0x03, 0x80, 0x81};
  849. hex = HexEncode(bytes, sizeof(bytes));
  850. EXPECT_EQ(hex.compare("01FF02FE038081"), 0);
  851. }
  852. // Test cases of known-bad strtod conversions that motivated the use of dmg_fp.
  853. // See https://bugs.chromium.org/p/chromium/issues/detail?id=593512.
  854. TEST(StringNumberConversionsTest, StrtodFailures) {
  855. static const struct {
  856. const char* input;
  857. uint64_t expected;
  858. } cases[] = {
  859. // http://www.exploringbinary.com/incorrectly-rounded-conversions-in-visual-c-plus-plus/
  860. {"9214843084008499", 0x43405e6cec57761aULL},
  861. {"0.500000000000000166533453693773481063544750213623046875",
  862. 0x3fe0000000000002ULL},
  863. {"30078505129381147446200", 0x44997a3c7271b021ULL},
  864. {"1777820000000000000001", 0x4458180d5bad2e3eULL},
  865. {"0.500000000000000166547006220929549868969843373633921146392822265625",
  866. 0x3fe0000000000002ULL},
  867. {"0.50000000000000016656055874808561867439493653364479541778564453125",
  868. 0x3fe0000000000002ULL},
  869. {"0.3932922657273", 0x3fd92bb352c4623aULL},
  870. // http://www.exploringbinary.com/incorrectly-rounded-conversions-in-gcc-and-glibc/
  871. {"0.500000000000000166533453693773481063544750213623046875",
  872. 0x3fe0000000000002ULL},
  873. {"3.518437208883201171875e13", 0x42c0000000000002ULL},
  874. {"62.5364939768271845828", 0x404f44abd5aa7ca4ULL},
  875. {"8.10109172351e-10", 0x3e0bd5cbaef0fd0cULL},
  876. {"1.50000000000000011102230246251565404236316680908203125",
  877. 0x3ff8000000000000ULL},
  878. {"9007199254740991.4999999999999999999999999999999995",
  879. 0x433fffffffffffffULL},
  880. // http://www.exploringbinary.com/incorrect-decimal-to-floating-point-conversion-in-sqlite/
  881. {"1e-23", 0x3b282db34012b251ULL},
  882. {"8.533e+68", 0x4e3fa69165a8eea2ULL},
  883. {"4.1006e-184", 0x19dbe0d1c7ea60c9ULL},
  884. {"9.998e+307", 0x7fe1cc0a350ca87bULL},
  885. {"9.9538452227e-280", 0x0602117ae45cde43ULL},
  886. {"6.47660115e-260", 0x0a1fdd9e333badadULL},
  887. {"7.4e+47", 0x49e033d7eca0adefULL},
  888. {"5.92e+48", 0x4a1033d7eca0adefULL},
  889. {"7.35e+66", 0x4dd172b70eababa9ULL},
  890. {"8.32116e+55", 0x4b8b2628393e02cdULL},
  891. };
  892. for (const auto& test : cases) {
  893. SCOPED_TRACE(StringPrintf("input: \"%s\"", test.input));
  894. double output;
  895. EXPECT_TRUE(StringToDouble(test.input, &output));
  896. EXPECT_EQ(bit_cast<uint64_t>(output), test.expected);
  897. }
  898. }
  899. } // namespace base