You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

util_tests.cpp 27KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. // Copyright (c) 2011-2016 The Starwels developers
  2. // Distributed under the MIT software license, see the accompanying
  3. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
  4. #include "util.h"
  5. #include "clientversion.h"
  6. #include "primitives/transaction.h"
  7. #include "sync.h"
  8. #include "utilstrencodings.h"
  9. #include "utilmoneystr.h"
  10. #include "test/test_starwels.h"
  11. #include <stdint.h>
  12. #include <vector>
  13. #include <boost/test/unit_test.hpp>
  14. BOOST_FIXTURE_TEST_SUITE(util_tests, BasicTestingSetup)
  15. BOOST_AUTO_TEST_CASE(util_criticalsection)
  16. {
  17. CCriticalSection cs;
  18. do {
  19. LOCK(cs);
  20. break;
  21. BOOST_ERROR("break was swallowed!");
  22. } while(0);
  23. do {
  24. TRY_LOCK(cs, lockTest);
  25. if (lockTest)
  26. break;
  27. BOOST_ERROR("break was swallowed!");
  28. } while(0);
  29. }
  30. static const unsigned char ParseHex_expected[65] = {
  31. 0x04, 0xea, 0x1e, 0x6e, 0x7c, 0xac, 0xe7, 0xb6, 0x3b, 0x88, 0x94, 0x9a, 0x3f, 0x43, 0xf0, 0x14,
  32. 0x4b, 0x00, 0x32, 0xea, 0xa9, 0xee, 0x6c, 0x96, 0x27, 0xfc, 0x58, 0xbf, 0xb5, 0x11, 0x63, 0xa2,
  33. 0x62, 0x54, 0x2f, 0xd8, 0xcd, 0xd3, 0xcc, 0x40, 0x18, 0x6a, 0x1a, 0xee, 0xb4, 0x85, 0x7c, 0x15,
  34. 0x95, 0x4e, 0x6f, 0x15, 0xf7, 0x89, 0xbf, 0xdc, 0xf9, 0xce, 0xc5, 0x98, 0x63, 0xcd, 0xfc, 0x6e,
  35. 0x14
  36. };
  37. BOOST_AUTO_TEST_CASE(util_ParseHex)
  38. {
  39. std::vector<unsigned char> result;
  40. std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
  41. // Basic test vector
  42. result = ParseHex("04ea1e6e7cace7b63b88949a3f43f0144b0032eaa9ee6c9627fc58bfb51163a262542fd8cdd3cc40186a1aeeb4857c15954e6f15f789bfdcf9cec59863cdfc6e14");
  43. BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
  44. // Spaces between bytes must be supported
  45. result = ParseHex("12 34 56 78");
  46. BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
  47. // Leading space must be supported (used in CDBEnv::Salvage)
  48. result = ParseHex(" 89 34 56 78");
  49. BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
  50. // Stop parsing at invalid value
  51. result = ParseHex("1234 invalid 1234");
  52. BOOST_CHECK(result.size() == 2 && result[0] == 0x12 && result[1] == 0x34);
  53. }
  54. BOOST_AUTO_TEST_CASE(util_HexStr)
  55. {
  56. BOOST_CHECK_EQUAL(
  57. HexStr(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected)),
  58. "04ea1e6e7cace7b63b88949a3f43f0144b0032eaa9ee6c9627fc58bfb51163a262542fd8cdd3cc40186a1aeeb4857c15954e6f15f789bfdcf9cec59863cdfc6e14");
  59. BOOST_CHECK_EQUAL(
  60. HexStr(ParseHex_expected, ParseHex_expected + 5, true),
  61. "04 ea 1e 6e 7c");
  62. BOOST_CHECK_EQUAL(
  63. HexStr(ParseHex_expected, ParseHex_expected, true),
  64. "");
  65. std::vector<unsigned char> ParseHex_vec(ParseHex_expected, ParseHex_expected + 5);
  66. BOOST_CHECK_EQUAL(
  67. HexStr(ParseHex_vec, true),
  68. "04 ea 1e 6e 7c");
  69. }
  70. BOOST_AUTO_TEST_CASE(util_DateTimeStrFormat)
  71. {
  72. BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0), "1970-01-01 00:00:00");
  73. BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 0x7FFFFFFF), "2038-01-19 03:14:07");
  74. BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M:%S", 1317425777), "2011-09-30 23:36:17");
  75. BOOST_CHECK_EQUAL(DateTimeStrFormat("%Y-%m-%d %H:%M", 1317425777), "2011-09-30 23:36");
  76. BOOST_CHECK_EQUAL(DateTimeStrFormat("%a, %d %b %Y %H:%M:%S +0000", 1317425777), "Fri, 30 Sep 2011 23:36:17 +0000");
  77. }
  78. class TestArgsManager : public ArgsManager
  79. {
  80. public:
  81. std::map<std::string, std::string>& GetMapArgs()
  82. {
  83. return mapArgs;
  84. };
  85. const std::map<std::string, std::vector<std::string> >& GetMapMultiArgs()
  86. {
  87. return mapMultiArgs;
  88. };
  89. };
  90. BOOST_AUTO_TEST_CASE(util_ParseParameters)
  91. {
  92. TestArgsManager testArgs;
  93. const char *argv_test[] = {"-ignored", "-a", "-b", "-ccc=argument", "-ccc=multiple", "f", "-d=e"};
  94. testArgs.ParseParameters(0, (char**)argv_test);
  95. BOOST_CHECK(testArgs.GetMapArgs().empty() && testArgs.GetMapMultiArgs().empty());
  96. testArgs.ParseParameters(1, (char**)argv_test);
  97. BOOST_CHECK(testArgs.GetMapArgs().empty() && testArgs.GetMapMultiArgs().empty());
  98. testArgs.ParseParameters(5, (char**)argv_test);
  99. // expectation: -ignored is ignored (program name argument),
  100. // -a, -b and -ccc end up in map, -d ignored because it is after
  101. // a non-option argument (non-GNU option parsing)
  102. BOOST_CHECK(testArgs.GetMapArgs().size() == 3 && testArgs.GetMapMultiArgs().size() == 3);
  103. BOOST_CHECK(testArgs.IsArgSet("-a") && testArgs.IsArgSet("-b") && testArgs.IsArgSet("-ccc")
  104. && !testArgs.IsArgSet("f") && !testArgs.IsArgSet("-d"));
  105. BOOST_CHECK(testArgs.GetMapMultiArgs().count("-a") && testArgs.GetMapMultiArgs().count("-b") && testArgs.GetMapMultiArgs().count("-ccc")
  106. && !testArgs.GetMapMultiArgs().count("f") && !testArgs.GetMapMultiArgs().count("-d"));
  107. BOOST_CHECK(testArgs.GetMapArgs()["-a"] == "" && testArgs.GetMapArgs()["-ccc"] == "multiple");
  108. BOOST_CHECK(testArgs.GetArgs("-ccc").size() == 2);
  109. }
  110. BOOST_AUTO_TEST_CASE(util_GetArg)
  111. {
  112. TestArgsManager testArgs;
  113. testArgs.GetMapArgs().clear();
  114. testArgs.GetMapArgs()["strtest1"] = "string...";
  115. // strtest2 undefined on purpose
  116. testArgs.GetMapArgs()["inttest1"] = "12345";
  117. testArgs.GetMapArgs()["inttest2"] = "81985529216486895";
  118. // inttest3 undefined on purpose
  119. testArgs.GetMapArgs()["booltest1"] = "";
  120. // booltest2 undefined on purpose
  121. testArgs.GetMapArgs()["booltest3"] = "0";
  122. testArgs.GetMapArgs()["booltest4"] = "1";
  123. BOOST_CHECK_EQUAL(testArgs.GetArg("strtest1", "default"), "string...");
  124. BOOST_CHECK_EQUAL(testArgs.GetArg("strtest2", "default"), "default");
  125. BOOST_CHECK_EQUAL(testArgs.GetArg("inttest1", -1), 12345);
  126. BOOST_CHECK_EQUAL(testArgs.GetArg("inttest2", -1), 81985529216486895LL);
  127. BOOST_CHECK_EQUAL(testArgs.GetArg("inttest3", -1), -1);
  128. BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest1", false), true);
  129. BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest2", false), false);
  130. BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest3", false), false);
  131. BOOST_CHECK_EQUAL(testArgs.GetBoolArg("booltest4", false), true);
  132. }
  133. BOOST_AUTO_TEST_CASE(util_FormatMoney)
  134. {
  135. BOOST_CHECK_EQUAL(FormatMoney(0), "0.00");
  136. BOOST_CHECK_EQUAL(FormatMoney((COIN/10000)*123456789), "12345.6789");
  137. BOOST_CHECK_EQUAL(FormatMoney(-COIN), "-1.00");
  138. BOOST_CHECK_EQUAL(FormatMoney(COIN*100000000), "100000000.00");
  139. BOOST_CHECK_EQUAL(FormatMoney(COIN*10000000), "10000000.00");
  140. BOOST_CHECK_EQUAL(FormatMoney(COIN*1000000), "1000000.00");
  141. BOOST_CHECK_EQUAL(FormatMoney(COIN*100000), "100000.00");
  142. BOOST_CHECK_EQUAL(FormatMoney(COIN*10000), "10000.00");
  143. BOOST_CHECK_EQUAL(FormatMoney(COIN*1000), "1000.00");
  144. BOOST_CHECK_EQUAL(FormatMoney(COIN*100), "100.00");
  145. BOOST_CHECK_EQUAL(FormatMoney(COIN*10), "10.00");
  146. BOOST_CHECK_EQUAL(FormatMoney(COIN), "1.00");
  147. BOOST_CHECK_EQUAL(FormatMoney(COIN/10), "0.10");
  148. BOOST_CHECK_EQUAL(FormatMoney(COIN/100), "0.01");
  149. BOOST_CHECK_EQUAL(FormatMoney(COIN/1000), "0.001");
  150. BOOST_CHECK_EQUAL(FormatMoney(COIN/10000), "0.0001");
  151. BOOST_CHECK_EQUAL(FormatMoney(COIN/100000), "0.00001");
  152. BOOST_CHECK_EQUAL(FormatMoney(COIN/1000000), "0.000001");
  153. BOOST_CHECK_EQUAL(FormatMoney(COIN/10000000), "0.0000001");
  154. BOOST_CHECK_EQUAL(FormatMoney(COIN/100000000), "0.00000001");
  155. }
  156. BOOST_AUTO_TEST_CASE(util_ParseMoney)
  157. {
  158. CAmount ret = 0;
  159. BOOST_CHECK(ParseMoney("0.0", ret));
  160. BOOST_CHECK_EQUAL(ret, 0);
  161. BOOST_CHECK(ParseMoney("12345.6789", ret));
  162. BOOST_CHECK_EQUAL(ret, (COIN/10000)*123456789);
  163. BOOST_CHECK(ParseMoney("100000000.00", ret));
  164. BOOST_CHECK_EQUAL(ret, COIN*100000000);
  165. BOOST_CHECK(ParseMoney("10000000.00", ret));
  166. BOOST_CHECK_EQUAL(ret, COIN*10000000);
  167. BOOST_CHECK(ParseMoney("1000000.00", ret));
  168. BOOST_CHECK_EQUAL(ret, COIN*1000000);
  169. BOOST_CHECK(ParseMoney("100000.00", ret));
  170. BOOST_CHECK_EQUAL(ret, COIN*100000);
  171. BOOST_CHECK(ParseMoney("10000.00", ret));
  172. BOOST_CHECK_EQUAL(ret, COIN*10000);
  173. BOOST_CHECK(ParseMoney("1000.00", ret));
  174. BOOST_CHECK_EQUAL(ret, COIN*1000);
  175. BOOST_CHECK(ParseMoney("100.00", ret));
  176. BOOST_CHECK_EQUAL(ret, COIN*100);
  177. BOOST_CHECK(ParseMoney("10.00", ret));
  178. BOOST_CHECK_EQUAL(ret, COIN*10);
  179. BOOST_CHECK(ParseMoney("1.00", ret));
  180. BOOST_CHECK_EQUAL(ret, COIN);
  181. BOOST_CHECK(ParseMoney("1", ret));
  182. BOOST_CHECK_EQUAL(ret, COIN);
  183. BOOST_CHECK(ParseMoney("0.1", ret));
  184. BOOST_CHECK_EQUAL(ret, COIN/10);
  185. BOOST_CHECK(ParseMoney("0.01", ret));
  186. BOOST_CHECK_EQUAL(ret, COIN/100);
  187. BOOST_CHECK(ParseMoney("0.001", ret));
  188. BOOST_CHECK_EQUAL(ret, COIN/1000);
  189. BOOST_CHECK(ParseMoney("0.0001", ret));
  190. BOOST_CHECK_EQUAL(ret, COIN/10000);
  191. BOOST_CHECK(ParseMoney("0.00001", ret));
  192. BOOST_CHECK_EQUAL(ret, COIN/100000);
  193. BOOST_CHECK(ParseMoney("0.000001", ret));
  194. BOOST_CHECK_EQUAL(ret, COIN/1000000);
  195. BOOST_CHECK(ParseMoney("0.0000001", ret));
  196. BOOST_CHECK_EQUAL(ret, COIN/10000000);
  197. BOOST_CHECK(ParseMoney("0.00000001", ret));
  198. BOOST_CHECK_EQUAL(ret, COIN/100000000);
  199. // Attempted 63 bit overflow should fail
  200. BOOST_CHECK(!ParseMoney("92233720368.54775808", ret));
  201. // Parsing negative amounts must fail
  202. BOOST_CHECK(!ParseMoney("-1", ret));
  203. }
  204. BOOST_AUTO_TEST_CASE(util_IsHex)
  205. {
  206. BOOST_CHECK(IsHex("00"));
  207. BOOST_CHECK(IsHex("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
  208. BOOST_CHECK(IsHex("ff"));
  209. BOOST_CHECK(IsHex("FF"));
  210. BOOST_CHECK(!IsHex(""));
  211. BOOST_CHECK(!IsHex("0"));
  212. BOOST_CHECK(!IsHex("a"));
  213. BOOST_CHECK(!IsHex("eleven"));
  214. BOOST_CHECK(!IsHex("00xx00"));
  215. BOOST_CHECK(!IsHex("0x0000"));
  216. }
  217. BOOST_AUTO_TEST_CASE(util_IsHexNumber)
  218. {
  219. BOOST_CHECK(IsHexNumber("0x0"));
  220. BOOST_CHECK(IsHexNumber("0"));
  221. BOOST_CHECK(IsHexNumber("0x10"));
  222. BOOST_CHECK(IsHexNumber("10"));
  223. BOOST_CHECK(IsHexNumber("0xff"));
  224. BOOST_CHECK(IsHexNumber("ff"));
  225. BOOST_CHECK(IsHexNumber("0xFfa"));
  226. BOOST_CHECK(IsHexNumber("Ffa"));
  227. BOOST_CHECK(IsHexNumber("0x00112233445566778899aabbccddeeffAABBCCDDEEFF"));
  228. BOOST_CHECK(IsHexNumber("00112233445566778899aabbccddeeffAABBCCDDEEFF"));
  229. BOOST_CHECK(!IsHexNumber("")); // empty string not allowed
  230. BOOST_CHECK(!IsHexNumber("0x")); // empty string after prefix not allowed
  231. BOOST_CHECK(!IsHexNumber("0x0 ")); // no spaces at end,
  232. BOOST_CHECK(!IsHexNumber(" 0x0")); // or beginning,
  233. BOOST_CHECK(!IsHexNumber("0x 0")); // or middle,
  234. BOOST_CHECK(!IsHexNumber(" ")); // etc.
  235. BOOST_CHECK(!IsHexNumber("0x0ga")); // invalid character
  236. BOOST_CHECK(!IsHexNumber("x0")); // broken prefix
  237. BOOST_CHECK(!IsHexNumber("0x0x00")); // two prefixes not allowed
  238. }
  239. BOOST_AUTO_TEST_CASE(util_seed_insecure_rand)
  240. {
  241. SeedInsecureRand(true);
  242. for (int mod=2;mod<11;mod++)
  243. {
  244. int mask = 1;
  245. // Really rough binomial confidence approximation.
  246. int err = 30*10000./mod*sqrt((1./mod*(1-1./mod))/10000.);
  247. //mask is 2^ceil(log2(mod))-1
  248. while(mask<mod-1)mask=(mask<<1)+1;
  249. int count = 0;
  250. //How often does it get a zero from the uniform range [0,mod)?
  251. for (int i = 0; i < 10000; i++) {
  252. uint32_t rval;
  253. do{
  254. rval=InsecureRand32()&mask;
  255. }while(rval>=(uint32_t)mod);
  256. count += rval==0;
  257. }
  258. BOOST_CHECK(count<=10000/mod+err);
  259. BOOST_CHECK(count>=10000/mod-err);
  260. }
  261. }
  262. BOOST_AUTO_TEST_CASE(util_TimingResistantEqual)
  263. {
  264. BOOST_CHECK(TimingResistantEqual(std::string(""), std::string("")));
  265. BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("")));
  266. BOOST_CHECK(!TimingResistantEqual(std::string(""), std::string("abc")));
  267. BOOST_CHECK(!TimingResistantEqual(std::string("a"), std::string("aa")));
  268. BOOST_CHECK(!TimingResistantEqual(std::string("aa"), std::string("a")));
  269. BOOST_CHECK(TimingResistantEqual(std::string("abc"), std::string("abc")));
  270. BOOST_CHECK(!TimingResistantEqual(std::string("abc"), std::string("aba")));
  271. }
  272. /* Test strprintf formatting directives.
  273. * Put a string before and after to ensure sanity of element sizes on stack. */
  274. #define B "check_prefix"
  275. #define E "check_postfix"
  276. BOOST_AUTO_TEST_CASE(strprintf_numbers)
  277. {
  278. int64_t s64t = -9223372036854775807LL; /* signed 64 bit test value */
  279. uint64_t u64t = 18446744073709551615ULL; /* unsigned 64 bit test value */
  280. BOOST_CHECK(strprintf("%s %d %s", B, s64t, E) == B" -9223372036854775807 " E);
  281. BOOST_CHECK(strprintf("%s %u %s", B, u64t, E) == B" 18446744073709551615 " E);
  282. BOOST_CHECK(strprintf("%s %x %s", B, u64t, E) == B" ffffffffffffffff " E);
  283. size_t st = 12345678; /* unsigned size_t test value */
  284. ssize_t sst = -12345678; /* signed size_t test value */
  285. BOOST_CHECK(strprintf("%s %d %s", B, sst, E) == B" -12345678 " E);
  286. BOOST_CHECK(strprintf("%s %u %s", B, st, E) == B" 12345678 " E);
  287. BOOST_CHECK(strprintf("%s %x %s", B, st, E) == B" bc614e " E);
  288. ptrdiff_t pt = 87654321; /* positive ptrdiff_t test value */
  289. ptrdiff_t spt = -87654321; /* negative ptrdiff_t test value */
  290. BOOST_CHECK(strprintf("%s %d %s", B, spt, E) == B" -87654321 " E);
  291. BOOST_CHECK(strprintf("%s %u %s", B, pt, E) == B" 87654321 " E);
  292. BOOST_CHECK(strprintf("%s %x %s", B, pt, E) == B" 5397fb1 " E);
  293. }
  294. #undef B
  295. #undef E
  296. /* Check for mingw/wine issue #3494
  297. * Remove this test before time.ctime(0xffffffff) == 'Sun Feb 7 07:28:15 2106'
  298. */
  299. BOOST_AUTO_TEST_CASE(gettime)
  300. {
  301. BOOST_CHECK((GetTime() & ~0xFFFFFFFFLL) == 0);
  302. }
  303. BOOST_AUTO_TEST_CASE(test_ParseInt32)
  304. {
  305. int32_t n;
  306. // Valid values
  307. BOOST_CHECK(ParseInt32("1234", nullptr));
  308. BOOST_CHECK(ParseInt32("0", &n) && n == 0);
  309. BOOST_CHECK(ParseInt32("1234", &n) && n == 1234);
  310. BOOST_CHECK(ParseInt32("01234", &n) && n == 1234); // no octal
  311. BOOST_CHECK(ParseInt32("2147483647", &n) && n == 2147483647);
  312. BOOST_CHECK(ParseInt32("-2147483648", &n) && n == (-2147483647 - 1)); // (-2147483647 - 1) equals INT_MIN
  313. BOOST_CHECK(ParseInt32("-1234", &n) && n == -1234);
  314. // Invalid values
  315. BOOST_CHECK(!ParseInt32("", &n));
  316. BOOST_CHECK(!ParseInt32(" 1", &n)); // no padding inside
  317. BOOST_CHECK(!ParseInt32("1 ", &n));
  318. BOOST_CHECK(!ParseInt32("1a", &n));
  319. BOOST_CHECK(!ParseInt32("aap", &n));
  320. BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
  321. BOOST_CHECK(!ParseInt32("0x1", &n)); // no hex
  322. const char test_bytes[] = {'1', 0, '1'};
  323. std::string teststr(test_bytes, sizeof(test_bytes));
  324. BOOST_CHECK(!ParseInt32(teststr, &n)); // no embedded NULs
  325. // Overflow and underflow
  326. BOOST_CHECK(!ParseInt32("-2147483649", nullptr));
  327. BOOST_CHECK(!ParseInt32("2147483648", nullptr));
  328. BOOST_CHECK(!ParseInt32("-32482348723847471234", nullptr));
  329. BOOST_CHECK(!ParseInt32("32482348723847471234", nullptr));
  330. }
  331. BOOST_AUTO_TEST_CASE(test_ParseInt64)
  332. {
  333. int64_t n;
  334. // Valid values
  335. BOOST_CHECK(ParseInt64("1234", nullptr));
  336. BOOST_CHECK(ParseInt64("0", &n) && n == 0LL);
  337. BOOST_CHECK(ParseInt64("1234", &n) && n == 1234LL);
  338. BOOST_CHECK(ParseInt64("01234", &n) && n == 1234LL); // no octal
  339. BOOST_CHECK(ParseInt64("2147483647", &n) && n == 2147483647LL);
  340. BOOST_CHECK(ParseInt64("-2147483648", &n) && n == -2147483648LL);
  341. BOOST_CHECK(ParseInt64("9223372036854775807", &n) && n == (int64_t)9223372036854775807);
  342. BOOST_CHECK(ParseInt64("-9223372036854775808", &n) && n == (int64_t)-9223372036854775807-1);
  343. BOOST_CHECK(ParseInt64("-1234", &n) && n == -1234LL);
  344. // Invalid values
  345. BOOST_CHECK(!ParseInt64("", &n));
  346. BOOST_CHECK(!ParseInt64(" 1", &n)); // no padding inside
  347. BOOST_CHECK(!ParseInt64("1 ", &n));
  348. BOOST_CHECK(!ParseInt64("1a", &n));
  349. BOOST_CHECK(!ParseInt64("aap", &n));
  350. BOOST_CHECK(!ParseInt64("0x1", &n)); // no hex
  351. const char test_bytes[] = {'1', 0, '1'};
  352. std::string teststr(test_bytes, sizeof(test_bytes));
  353. BOOST_CHECK(!ParseInt64(teststr, &n)); // no embedded NULs
  354. // Overflow and underflow
  355. BOOST_CHECK(!ParseInt64("-9223372036854775809", nullptr));
  356. BOOST_CHECK(!ParseInt64("9223372036854775808", nullptr));
  357. BOOST_CHECK(!ParseInt64("-32482348723847471234", nullptr));
  358. BOOST_CHECK(!ParseInt64("32482348723847471234", nullptr));
  359. }
  360. BOOST_AUTO_TEST_CASE(test_ParseUInt32)
  361. {
  362. uint32_t n;
  363. // Valid values
  364. BOOST_CHECK(ParseUInt32("1234", nullptr));
  365. BOOST_CHECK(ParseUInt32("0", &n) && n == 0);
  366. BOOST_CHECK(ParseUInt32("1234", &n) && n == 1234);
  367. BOOST_CHECK(ParseUInt32("01234", &n) && n == 1234); // no octal
  368. BOOST_CHECK(ParseUInt32("2147483647", &n) && n == 2147483647);
  369. BOOST_CHECK(ParseUInt32("2147483648", &n) && n == (uint32_t)2147483648);
  370. BOOST_CHECK(ParseUInt32("4294967295", &n) && n == (uint32_t)4294967295);
  371. // Invalid values
  372. BOOST_CHECK(!ParseUInt32("", &n));
  373. BOOST_CHECK(!ParseUInt32(" 1", &n)); // no padding inside
  374. BOOST_CHECK(!ParseUInt32(" -1", &n));
  375. BOOST_CHECK(!ParseUInt32("1 ", &n));
  376. BOOST_CHECK(!ParseUInt32("1a", &n));
  377. BOOST_CHECK(!ParseUInt32("aap", &n));
  378. BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
  379. BOOST_CHECK(!ParseUInt32("0x1", &n)); // no hex
  380. const char test_bytes[] = {'1', 0, '1'};
  381. std::string teststr(test_bytes, sizeof(test_bytes));
  382. BOOST_CHECK(!ParseUInt32(teststr, &n)); // no embedded NULs
  383. // Overflow and underflow
  384. BOOST_CHECK(!ParseUInt32("-2147483648", &n));
  385. BOOST_CHECK(!ParseUInt32("4294967296", &n));
  386. BOOST_CHECK(!ParseUInt32("-1234", &n));
  387. BOOST_CHECK(!ParseUInt32("-32482348723847471234", nullptr));
  388. BOOST_CHECK(!ParseUInt32("32482348723847471234", nullptr));
  389. }
  390. BOOST_AUTO_TEST_CASE(test_ParseUInt64)
  391. {
  392. uint64_t n;
  393. // Valid values
  394. BOOST_CHECK(ParseUInt64("1234", nullptr));
  395. BOOST_CHECK(ParseUInt64("0", &n) && n == 0LL);
  396. BOOST_CHECK(ParseUInt64("1234", &n) && n == 1234LL);
  397. BOOST_CHECK(ParseUInt64("01234", &n) && n == 1234LL); // no octal
  398. BOOST_CHECK(ParseUInt64("2147483647", &n) && n == 2147483647LL);
  399. BOOST_CHECK(ParseUInt64("9223372036854775807", &n) && n == 9223372036854775807ULL);
  400. BOOST_CHECK(ParseUInt64("9223372036854775808", &n) && n == 9223372036854775808ULL);
  401. BOOST_CHECK(ParseUInt64("18446744073709551615", &n) && n == 18446744073709551615ULL);
  402. // Invalid values
  403. BOOST_CHECK(!ParseUInt64("", &n));
  404. BOOST_CHECK(!ParseUInt64(" 1", &n)); // no padding inside
  405. BOOST_CHECK(!ParseUInt64(" -1", &n));
  406. BOOST_CHECK(!ParseUInt64("1 ", &n));
  407. BOOST_CHECK(!ParseUInt64("1a", &n));
  408. BOOST_CHECK(!ParseUInt64("aap", &n));
  409. BOOST_CHECK(!ParseUInt64("0x1", &n)); // no hex
  410. const char test_bytes[] = {'1', 0, '1'};
  411. std::string teststr(test_bytes, sizeof(test_bytes));
  412. BOOST_CHECK(!ParseUInt64(teststr, &n)); // no embedded NULs
  413. // Overflow and underflow
  414. BOOST_CHECK(!ParseUInt64("-9223372036854775809", nullptr));
  415. BOOST_CHECK(!ParseUInt64("18446744073709551616", nullptr));
  416. BOOST_CHECK(!ParseUInt64("-32482348723847471234", nullptr));
  417. BOOST_CHECK(!ParseUInt64("-2147483648", &n));
  418. BOOST_CHECK(!ParseUInt64("-9223372036854775808", &n));
  419. BOOST_CHECK(!ParseUInt64("-1234", &n));
  420. }
  421. BOOST_AUTO_TEST_CASE(test_ParseDouble)
  422. {
  423. double n;
  424. // Valid values
  425. BOOST_CHECK(ParseDouble("1234", nullptr));
  426. BOOST_CHECK(ParseDouble("0", &n) && n == 0.0);
  427. BOOST_CHECK(ParseDouble("1234", &n) && n == 1234.0);
  428. BOOST_CHECK(ParseDouble("01234", &n) && n == 1234.0); // no octal
  429. BOOST_CHECK(ParseDouble("2147483647", &n) && n == 2147483647.0);
  430. BOOST_CHECK(ParseDouble("-2147483648", &n) && n == -2147483648.0);
  431. BOOST_CHECK(ParseDouble("-1234", &n) && n == -1234.0);
  432. BOOST_CHECK(ParseDouble("1e6", &n) && n == 1e6);
  433. BOOST_CHECK(ParseDouble("-1e6", &n) && n == -1e6);
  434. // Invalid values
  435. BOOST_CHECK(!ParseDouble("", &n));
  436. BOOST_CHECK(!ParseDouble(" 1", &n)); // no padding inside
  437. BOOST_CHECK(!ParseDouble("1 ", &n));
  438. BOOST_CHECK(!ParseDouble("1a", &n));
  439. BOOST_CHECK(!ParseDouble("aap", &n));
  440. BOOST_CHECK(!ParseDouble("0x1", &n)); // no hex
  441. const char test_bytes[] = {'1', 0, '1'};
  442. std::string teststr(test_bytes, sizeof(test_bytes));
  443. BOOST_CHECK(!ParseDouble(teststr, &n)); // no embedded NULs
  444. // Overflow and underflow
  445. BOOST_CHECK(!ParseDouble("-1e10000", nullptr));
  446. BOOST_CHECK(!ParseDouble("1e10000", nullptr));
  447. }
  448. BOOST_AUTO_TEST_CASE(test_FormatParagraph)
  449. {
  450. BOOST_CHECK_EQUAL(FormatParagraph("", 79, 0), "");
  451. BOOST_CHECK_EQUAL(FormatParagraph("test", 79, 0), "test");
  452. BOOST_CHECK_EQUAL(FormatParagraph(" test", 79, 0), " test");
  453. BOOST_CHECK_EQUAL(FormatParagraph("test test", 79, 0), "test test");
  454. BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 0), "test\ntest");
  455. BOOST_CHECK_EQUAL(FormatParagraph("testerde test", 4, 0), "testerde\ntest");
  456. BOOST_CHECK_EQUAL(FormatParagraph("test test", 4, 4), "test\n test");
  457. // Make sure we don't indent a fully-new line following a too-long line ending
  458. BOOST_CHECK_EQUAL(FormatParagraph("test test\nabc", 4, 4), "test\n test\nabc");
  459. BOOST_CHECK_EQUAL(FormatParagraph("This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length until it gets here", 79), "This_is_a_very_long_test_string_without_any_spaces_so_it_should_just_get_returned_as_is_despite_the_length\nuntil it gets here");
  460. // Test wrap length is exact
  461. BOOST_CHECK_EQUAL(FormatParagraph("a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "a b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p");
  462. BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p", 79), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\nf g h i j k l m n o p");
  463. // Indent should be included in length of lines
  464. BOOST_CHECK_EQUAL(FormatParagraph("x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg h i j k", 79, 4), "x\na b c d e f g h i j k l m n o p q r s t u v w x y z 1 2 3 4 5 6 7 8 9 a b c de\n f g h i j k l m n o p q r s t u v w x y z 0 1 2 3 4 5 6 7 8 9 a b c d e fg\n h i j k");
  465. BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string. This is a second sentence in the very long test string.", 79), "This is a very long test string. This is a second sentence in the very long\ntest string.");
  466. BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string.");
  467. BOOST_CHECK_EQUAL(FormatParagraph("This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third sentence in the very long test string.", 79), "This is a very long test string.\n\nThis is a second sentence in the very long test string. This is a third\nsentence in the very long test string.");
  468. BOOST_CHECK_EQUAL(FormatParagraph("Testing that normal newlines do not get indented.\nLike here.", 79), "Testing that normal newlines do not get indented.\nLike here.");
  469. }
  470. BOOST_AUTO_TEST_CASE(test_FormatSubVersion)
  471. {
  472. std::vector<std::string> comments;
  473. comments.push_back(std::string("comment1"));
  474. std::vector<std::string> comments2;
  475. comments2.push_back(std::string("comment1"));
  476. comments2.push_back(SanitizeString(std::string("Comment2; .,_?@-; !\"#$%&'()*+/<=>[]\\^`{|}~"), SAFE_CHARS_UA_COMMENT)); // Semicolon is discouraged but not forbidden by BIP-0014
  477. BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, std::vector<std::string>()),std::string("/Test:0.9.99/"));
  478. BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments),std::string("/Test:0.9.99(comment1)/"));
  479. BOOST_CHECK_EQUAL(FormatSubVersion("Test", 99900, comments2),std::string("/Test:0.9.99(comment1; Comment2; .,_?@-; )/"));
  480. }
  481. BOOST_AUTO_TEST_CASE(test_ParseFixedPoint)
  482. {
  483. int64_t amount = 0;
  484. BOOST_CHECK(ParseFixedPoint("0", 8, &amount));
  485. BOOST_CHECK_EQUAL(amount, 0LL);
  486. BOOST_CHECK(ParseFixedPoint("1", 8, &amount));
  487. BOOST_CHECK_EQUAL(amount, 100000000LL);
  488. BOOST_CHECK(ParseFixedPoint("0.0", 8, &amount));
  489. BOOST_CHECK_EQUAL(amount, 0LL);
  490. BOOST_CHECK(ParseFixedPoint("-0.1", 8, &amount));
  491. BOOST_CHECK_EQUAL(amount, -10000000LL);
  492. BOOST_CHECK(ParseFixedPoint("1.1", 8, &amount));
  493. BOOST_CHECK_EQUAL(amount, 110000000LL);
  494. BOOST_CHECK(ParseFixedPoint("1.10000000000000000", 8, &amount));
  495. BOOST_CHECK_EQUAL(amount, 110000000LL);
  496. BOOST_CHECK(ParseFixedPoint("1.1e1", 8, &amount));
  497. BOOST_CHECK_EQUAL(amount, 1100000000LL);
  498. BOOST_CHECK(ParseFixedPoint("1.1e-1", 8, &amount));
  499. BOOST_CHECK_EQUAL(amount, 11000000LL);
  500. BOOST_CHECK(ParseFixedPoint("1000", 8, &amount));
  501. BOOST_CHECK_EQUAL(amount, 100000000000LL);
  502. BOOST_CHECK(ParseFixedPoint("-1000", 8, &amount));
  503. BOOST_CHECK_EQUAL(amount, -100000000000LL);
  504. BOOST_CHECK(ParseFixedPoint("0.00000001", 8, &amount));
  505. BOOST_CHECK_EQUAL(amount, 1LL);
  506. BOOST_CHECK(ParseFixedPoint("0.0000000100000000", 8, &amount));
  507. BOOST_CHECK_EQUAL(amount, 1LL);
  508. BOOST_CHECK(ParseFixedPoint("-0.00000001", 8, &amount));
  509. BOOST_CHECK_EQUAL(amount, -1LL);
  510. BOOST_CHECK(ParseFixedPoint("1000000000.00000001", 8, &amount));
  511. BOOST_CHECK_EQUAL(amount, 100000000000000001LL);
  512. BOOST_CHECK(ParseFixedPoint("9999999999.99999999", 8, &amount));
  513. BOOST_CHECK_EQUAL(amount, 999999999999999999LL);
  514. BOOST_CHECK(ParseFixedPoint("-9999999999.99999999", 8, &amount));
  515. BOOST_CHECK_EQUAL(amount, -999999999999999999LL);
  516. BOOST_CHECK(!ParseFixedPoint("", 8, &amount));
  517. BOOST_CHECK(!ParseFixedPoint("-", 8, &amount));
  518. BOOST_CHECK(!ParseFixedPoint("a-1000", 8, &amount));
  519. BOOST_CHECK(!ParseFixedPoint("-a1000", 8, &amount));
  520. BOOST_CHECK(!ParseFixedPoint("-1000a", 8, &amount));
  521. BOOST_CHECK(!ParseFixedPoint("-01000", 8, &amount));
  522. BOOST_CHECK(!ParseFixedPoint("00.1", 8, &amount));
  523. BOOST_CHECK(!ParseFixedPoint(".1", 8, &amount));
  524. BOOST_CHECK(!ParseFixedPoint("--0.1", 8, &amount));
  525. BOOST_CHECK(!ParseFixedPoint("0.000000001", 8, &amount));
  526. BOOST_CHECK(!ParseFixedPoint("-0.000000001", 8, &amount));
  527. BOOST_CHECK(!ParseFixedPoint("0.00000001000000001", 8, &amount));
  528. BOOST_CHECK(!ParseFixedPoint("-10000000000.00000000", 8, &amount));
  529. BOOST_CHECK(!ParseFixedPoint("10000000000.00000000", 8, &amount));
  530. BOOST_CHECK(!ParseFixedPoint("-10000000000.00000001", 8, &amount));
  531. BOOST_CHECK(!ParseFixedPoint("10000000000.00000001", 8, &amount));
  532. BOOST_CHECK(!ParseFixedPoint("-10000000000.00000009", 8, &amount));
  533. BOOST_CHECK(!ParseFixedPoint("10000000000.00000009", 8, &amount));
  534. BOOST_CHECK(!ParseFixedPoint("-99999999999.99999999", 8, &amount));
  535. BOOST_CHECK(!ParseFixedPoint("99999909999.09999999", 8, &amount));
  536. BOOST_CHECK(!ParseFixedPoint("92233720368.54775807", 8, &amount));
  537. BOOST_CHECK(!ParseFixedPoint("92233720368.54775808", 8, &amount));
  538. BOOST_CHECK(!ParseFixedPoint("-92233720368.54775808", 8, &amount));
  539. BOOST_CHECK(!ParseFixedPoint("-92233720368.54775809", 8, &amount));
  540. BOOST_CHECK(!ParseFixedPoint("1.1e", 8, &amount));
  541. BOOST_CHECK(!ParseFixedPoint("1.1e-", 8, &amount));
  542. BOOST_CHECK(!ParseFixedPoint("1.", 8, &amount));
  543. }
  544. BOOST_AUTO_TEST_SUITE_END()