TestSnprintf.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /*
  2. * Copyright (c) 2020, Ben Wiederhake <BenWiederhake.GitHub@gmx.de>
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <LibTest/TestCase.h>
  7. #include <AK/ByteBuffer.h>
  8. #include <AK/Random.h>
  9. #include <AK/StringBuilder.h>
  10. #include <ctype.h>
  11. #include <inttypes.h>
  12. #include <limits.h>
  13. #include <stdint.h>
  14. #include <stdio.h>
  15. #pragma GCC diagnostic ignored "-Wformat-nonliteral"
  16. template<typename TArg>
  17. struct Testcase {
  18. char const* dest;
  19. size_t dest_n;
  20. char const* fmt;
  21. const TArg arg;
  22. int expected_return;
  23. char const* dest_expected;
  24. size_t dest_expected_n; // == dest_n
  25. };
  26. static String show(ByteBuffer const& buf)
  27. {
  28. StringBuilder builder;
  29. for (size_t i = 0; i < buf.size(); ++i) {
  30. builder.appendff("{:02x}", buf[i]);
  31. }
  32. builder.append(' ');
  33. builder.append('(');
  34. for (size_t i = 0; i < buf.size(); ++i) {
  35. if (isprint(buf[i]))
  36. builder.append(buf[i]);
  37. else
  38. builder.append('_');
  39. }
  40. builder.append(')');
  41. return builder.build();
  42. }
  43. template<typename TArg>
  44. static bool test_single(Testcase<TArg> const& testcase)
  45. {
  46. constexpr size_t SANDBOX_CANARY_SIZE = 8;
  47. // Preconditions:
  48. if (testcase.dest_n != testcase.dest_expected_n) {
  49. warnln("dest length {} != expected dest length {}? Check testcase! (Probably miscounted.)", testcase.dest_n, testcase.dest_expected_n);
  50. return false;
  51. }
  52. // Setup
  53. ByteBuffer actual = ByteBuffer::create_uninitialized(SANDBOX_CANARY_SIZE + testcase.dest_n + SANDBOX_CANARY_SIZE).release_value();
  54. fill_with_random(actual.data(), actual.size());
  55. ByteBuffer expected = actual;
  56. VERIFY(actual.offset_pointer(0) != expected.offset_pointer(0));
  57. actual.overwrite(SANDBOX_CANARY_SIZE, testcase.dest, testcase.dest_n);
  58. expected.overwrite(SANDBOX_CANARY_SIZE, testcase.dest_expected, testcase.dest_expected_n);
  59. // "unsigned char" != "char", so we have to convince the compiler to allow this.
  60. char* dst = reinterpret_cast<char*>(actual.offset_pointer(SANDBOX_CANARY_SIZE));
  61. // The actual call:
  62. int actual_return = snprintf(dst, testcase.dest_n, testcase.fmt, testcase.arg);
  63. // Checking the results:
  64. bool return_ok = actual_return == testcase.expected_return;
  65. bool canary_1_ok = MUST(actual.slice(0, SANDBOX_CANARY_SIZE)) == MUST(expected.slice(0, SANDBOX_CANARY_SIZE));
  66. bool main_ok = MUST(actual.slice(SANDBOX_CANARY_SIZE, testcase.dest_n)) == MUST(expected.slice(SANDBOX_CANARY_SIZE, testcase.dest_n));
  67. bool canary_2_ok = MUST(actual.slice(SANDBOX_CANARY_SIZE + testcase.dest_n, SANDBOX_CANARY_SIZE)) == MUST(expected.slice(SANDBOX_CANARY_SIZE + testcase.dest_n, SANDBOX_CANARY_SIZE));
  68. bool buf_ok = actual == expected;
  69. // Evaluate gravity:
  70. if (buf_ok && (!canary_1_ok || !main_ok || !canary_2_ok)) {
  71. warnln("Internal error! ({} != {} | {} | {})", buf_ok, canary_1_ok, main_ok, canary_2_ok);
  72. buf_ok = false;
  73. }
  74. if (!canary_1_ok) {
  75. warnln("Canary 1 overwritten: Expected {}\n"
  76. " instead got {}",
  77. show(MUST(expected.slice(0, SANDBOX_CANARY_SIZE))),
  78. show(MUST(actual.slice(0, SANDBOX_CANARY_SIZE))));
  79. }
  80. if (!main_ok) {
  81. warnln("Wrong output: Expected {}\n"
  82. " instead, got {}",
  83. show(MUST(expected.slice(SANDBOX_CANARY_SIZE, testcase.dest_n))),
  84. show(MUST(actual.slice(SANDBOX_CANARY_SIZE, testcase.dest_n))));
  85. }
  86. if (!canary_2_ok) {
  87. warnln("Canary 2 overwritten: Expected {}\n"
  88. " instead, got {}",
  89. show(MUST(expected.slice(SANDBOX_CANARY_SIZE + testcase.dest_n, SANDBOX_CANARY_SIZE))),
  90. show(MUST(actual.slice(SANDBOX_CANARY_SIZE + testcase.dest_n, SANDBOX_CANARY_SIZE))));
  91. }
  92. if (!return_ok) {
  93. warnln("Wrong return value: Expected {}, got {} instead!", testcase.expected_return, actual_return);
  94. }
  95. return buf_ok && return_ok;
  96. }
  97. // Drop the NUL terminator added by the C++ compiler.
  98. #define LITERAL(x) x, (sizeof(x) - 1)
  99. static char const* const POISON = (char const*)1;
  100. TEST_CASE(golden_path)
  101. {
  102. EXPECT(test_single<char const*>({ LITERAL("Hello World!\0\0\0"), "Hello Friend!", POISON, 13, LITERAL("Hello Friend!\0\0") }));
  103. EXPECT(test_single<char const*>({ LITERAL("Hello World!\0\0\0"), "Hello %s!", "Friend", 13, LITERAL("Hello Friend!\0\0") }));
  104. EXPECT(test_single<char const*>({ LITERAL("aaaaaaaaaa"), "whf", POISON, 3, LITERAL("whf\0aaaaaa") }));
  105. EXPECT(test_single<char const*>({ LITERAL("aaaaaaaaaa"), "w%sf", "h", 3, LITERAL("whf\0aaaaaa") }));
  106. }
  107. TEST_CASE(border_cases)
  108. {
  109. EXPECT(test_single<char const*>({ LITERAL("Hello World!\0\0"), "Hello Friend!", POISON, 13, LITERAL("Hello Friend!\0") }));
  110. EXPECT(test_single<char const*>({ LITERAL("AAAA"), "whf", POISON, 3, LITERAL("whf\0") }));
  111. EXPECT(test_single<char const*>({ LITERAL("AAAA"), "%s", "whf", 3, LITERAL("whf\0") }));
  112. }
  113. TEST_CASE(too_long)
  114. {
  115. EXPECT(test_single<char const*>({ LITERAL("Hello World!\0"), "Hello Friend!", POISON, 13, LITERAL("Hello Friend\0") }));
  116. EXPECT(test_single<char const*>({ LITERAL("Hello World!\0"), "This source is %s too long!", "just *way*", 35, LITERAL("This source \0") }));
  117. EXPECT(test_single<char const*>({ LITERAL("x"), "This source is %s too long!", "just *way*", 35, LITERAL("\0") }));
  118. }
  119. TEST_CASE(special_cases)
  120. {
  121. EXPECT(test_single<char const*>({ LITERAL(""), "Hello Friend!", POISON, 13, LITERAL("") }));
  122. EXPECT_EQ(snprintf(nullptr, 0, "Hello, friend!"), 14);
  123. EXPECT(test_single<char const*>({ LITERAL(""), "", POISON, 0, LITERAL("") }));
  124. EXPECT(test_single<char const*>({ LITERAL("x"), "", POISON, 0, LITERAL("\0") }));
  125. EXPECT(test_single<char const*>({ LITERAL("xx"), "", POISON, 0, LITERAL("\0x") }));
  126. EXPECT(test_single<char const*>({ LITERAL("xxx"), "", POISON, 0, LITERAL("\0xx") }));
  127. EXPECT(test_single<char const*>({ LITERAL(""), "whf", POISON, 3, LITERAL("") }));
  128. EXPECT(test_single<char const*>({ LITERAL("x"), "whf", POISON, 3, LITERAL("\0") }));
  129. EXPECT(test_single<char const*>({ LITERAL("xx"), "whf", POISON, 3, LITERAL("w\0") }));
  130. }
  131. TEST_CASE(octal_values)
  132. {
  133. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5o|", 017, 12, LITERAL("| 00017|\0") }));
  134. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5o|", 01000, 12, LITERAL("| 01000|\0") }));
  135. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5o|", 010000, 12, LITERAL("| 010000|\0") }));
  136. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5o|", 017, 12, LITERAL("| 00017|\0") }));
  137. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-10.5o|", 017, 12, LITERAL("|00017 |\0") }));
  138. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-010.5o|", 017, 12, LITERAL("|00017 |\0") }));
  139. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010.5o|", 017, 12, LITERAL("| 00017|\0") }));
  140. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010o|", 017, 12, LITERAL("|0000000017|\0") }));
  141. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10o|", 017, 12, LITERAL("| 17|\0") }));
  142. EXPECT(test_single<int>({ LITERAL("xxxxxxx\0"), "|%.5o|", 017, 7, LITERAL("|00017|\0") }));
  143. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%.1o|", 017, 4, LITERAL("|17|\0") }));
  144. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%.0o|", 017, 4, LITERAL("|17|\0") }));
  145. EXPECT(test_single<int>({ LITERAL("xx\0"), "|%.0o|", 00, 2, LITERAL("||\0") }));
  146. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%#.0o|", 00, 3, LITERAL("|0|\0") }));
  147. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%#.0o|", 01, 4, LITERAL("|01|\0") }));
  148. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%#.1o|", 00, 3, LITERAL("|0|\0") }));
  149. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%#.1o|", 01, 4, LITERAL("|01|\0") }));
  150. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%o|", 00, 3, LITERAL("|0|\0") }));
  151. }
  152. TEST_CASE(decimal_values)
  153. {
  154. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5d|", 17, 12, LITERAL("| 00017|\0") }));
  155. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+10.5d|", 17, 12, LITERAL("| +00017|\0") }));
  156. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5d|", -17, 12, LITERAL("| -00017|\0") }));
  157. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+10.5d|", -17, 12, LITERAL("| -00017|\0") }));
  158. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-10.5d|", 17, 12, LITERAL("|00017 |\0") }));
  159. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+-10.5d|", 17, 12, LITERAL("|+00017 |\0") }));
  160. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+-10.5d|", -17, 12, LITERAL("|-00017 |\0") }));
  161. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-10.5d|", -17, 12, LITERAL("|-00017 |\0") }));
  162. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-010.5d|", 17, 12, LITERAL("|00017 |\0") }));
  163. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010.5d|", 17, 12, LITERAL("| 00017|\0") }));
  164. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010d|", 17, 12, LITERAL("|0000000017|\0") }));
  165. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+010d|", 17, 12, LITERAL("|+000000017|\0") }));
  166. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010d|", -17, 12, LITERAL("|-000000017|\0") }));
  167. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010d|", 170000000, 12, LITERAL("|0170000000|\0") }));
  168. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+010d|", 170000000, 12, LITERAL("|+170000000|\0") }));
  169. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10d|", -170000000, 12, LITERAL("|-170000000|\0") }));
  170. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+10d|", -170000000, 12, LITERAL("|-170000000|\0") }));
  171. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010d|", 1700000000, 12, LITERAL("|1700000000|\0") }));
  172. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxxx\0"), "|%+010d|", 1700000000, 13, LITERAL("|+1700000000|\0") }));
  173. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxxx\0"), "|%10d|", -1700000000, 13, LITERAL("|-1700000000|\0") }));
  174. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxxx\0"), "|%+10d|", -1700000000, 13, LITERAL("|-1700000000|\0") }));
  175. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10d|", 17, 12, LITERAL("| 17|\0") }));
  176. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+10d|", 17, 12, LITERAL("| +17|\0") }));
  177. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10d|", -17, 12, LITERAL("| -17|\0") }));
  178. EXPECT(test_single<int>({ LITERAL("xxxxxxx\0"), "|%.5d|", 17, 7, LITERAL("|00017|\0") }));
  179. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%.1d|", 17, 4, LITERAL("|17|\0") }));
  180. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%.0d|", 17, 4, LITERAL("|17|\0") }));
  181. EXPECT(test_single<int>({ LITERAL("xx\0"), "|%.0d|", 0, 2, LITERAL("||\0") }));
  182. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%+.0d|", 0, 3, LITERAL("|+|\0") }));
  183. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%#.1d|", 0, 3, LITERAL("|0|\0") }));
  184. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%d|", 0, 3, LITERAL("|0|\0") }));
  185. }
  186. TEST_CASE(unsigned_decimal_values)
  187. {
  188. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5u|", 17, 12, LITERAL("| 00017|\0") }));
  189. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+10.5u|", 17, 12, LITERAL("| 00017|\0") }));
  190. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-10.5u|", 17, 12, LITERAL("|00017 |\0") }));
  191. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+-10.5u|", 17, 12, LITERAL("|00017 |\0") }));
  192. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-010.5u|", 17, 12, LITERAL("|00017 |\0") }));
  193. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010.5u|", 17, 12, LITERAL("| 00017|\0") }));
  194. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010u|", 17, 12, LITERAL("|0000000017|\0") }));
  195. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+010u|", 17, 12, LITERAL("|0000000017|\0") }));
  196. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010u|", 170000000, 12, LITERAL("|0170000000|\0") }));
  197. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+010u|", 170000000, 12, LITERAL("|0170000000|\0") }));
  198. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010u|", 1700000000, 12, LITERAL("|1700000000|\0") }));
  199. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+010u|", 1700000000, 12, LITERAL("|1700000000|\0") }));
  200. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10u|", 17, 12, LITERAL("| 17|\0") }));
  201. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxx\0"), "|%+10u|", 17, 12, LITERAL("| 17|\0") }));
  202. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxx\0"), "|%.5u|", 17, 7, LITERAL("|00017|\0") }));
  203. EXPECT(test_single<unsigned int>({ LITERAL("xxxx\0"), "|%.1u|", 17, 4, LITERAL("|17|\0") }));
  204. EXPECT(test_single<unsigned int>({ LITERAL("xxxx\0"), "|%.0u|", 17, 4, LITERAL("|17|\0") }));
  205. EXPECT(test_single<unsigned int>({ LITERAL("xx\0"), "|%.0u|", 0, 2, LITERAL("||\0") }));
  206. EXPECT(test_single<unsigned int>({ LITERAL("xx\0"), "|%+.0u|", 0, 2, LITERAL("||\0") }));
  207. EXPECT(test_single<unsigned int>({ LITERAL("xxx\0"), "|%#.1u|", 0, 3, LITERAL("|0|\0") }));
  208. EXPECT(test_single<unsigned int>({ LITERAL("xxx\0"), "|%u|", 0, 3, LITERAL("|0|\0") }));
  209. }
  210. TEST_CASE(hexadecimal_values)
  211. {
  212. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5X|", 0xab, 12, LITERAL("| 000AB|\0") }));
  213. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5X|", 0xab, 12, LITERAL("| 0x000AB|\0") }));
  214. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5x|", 0xab, 12, LITERAL("| 000ab|\0") }));
  215. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5x|", 0xab, 12, LITERAL("| 0x000ab|\0") }));
  216. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5x|", 0x1000, 12, LITERAL("| 01000|\0") }));
  217. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5x|", 0x1000, 12, LITERAL("| 0x01000|\0") }));
  218. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5x|", 0x10000, 12, LITERAL("| 10000|\0") }));
  219. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10.5x|", 0x10000, 12, LITERAL("| 0x10000|\0") }));
  220. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10.5x|", 0x17, 12, LITERAL("| 00017|\0") }));
  221. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-#10.5x|", 0x17, 12, LITERAL("|0x00017 |\0") }));
  222. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-10.5x|", 0x17, 12, LITERAL("|00017 |\0") }));
  223. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%-010.5x|", 0x17, 12, LITERAL("|00017 |\0") }));
  224. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010.5x|", 0x17, 12, LITERAL("| 00017|\0") }));
  225. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%010x|", 0x17, 12, LITERAL("|0000000017|\0") }));
  226. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#010x|", 0x17, 12, LITERAL("|0x00000017|\0") }));
  227. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%10x|", 0x17, 12, LITERAL("| 17|\0") }));
  228. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxx\0"), "|%#10x|", 0x17, 12, LITERAL("| 0x17|\0") }));
  229. EXPECT(test_single<int>({ LITERAL("xxxxxxx\0"), "|%.5x|", 0x17, 7, LITERAL("|00017|\0") }));
  230. EXPECT(test_single<int>({ LITERAL("xxxxxxxxx\0"), "|%#.5x|", 0x17, 9, LITERAL("|0x00017|\0") }));
  231. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%.1x|", 0x17, 4, LITERAL("|17|\0") }));
  232. EXPECT(test_single<int>({ LITERAL("xxxx\0"), "|%.0x|", 0x17, 4, LITERAL("|17|\0") }));
  233. EXPECT(test_single<int>({ LITERAL("xx\0"), "|%.0x|", 0x0, 2, LITERAL("||\0") }));
  234. EXPECT(test_single<int>({ LITERAL("xx\0"), "|%#.0x|", 0x0, 2, LITERAL("||\0") }));
  235. EXPECT(test_single<int>({ LITERAL("xxxxxx\0"), "|%4.0x|", 0x0, 6, LITERAL("| |\0") }));
  236. EXPECT(test_single<int>({ LITERAL("xxxxxx\0"), "|%04.0x|", 0x0, 6, LITERAL("| |\0") }));
  237. EXPECT(test_single<int>({ LITERAL("xxxxxx\0"), "|%#4.0x|", 0x0, 6, LITERAL("| |\0") }));
  238. EXPECT(test_single<int>({ LITERAL("xxxxxx\0"), "|%#04.0x|", 0x0, 6, LITERAL("| |\0") }));
  239. EXPECT(test_single<int>({ LITERAL("xxxxx\0"), "|%#.0x|", 0x1, 5, LITERAL("|0x1|\0") }));
  240. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%#.1x|", 0x0, 3, LITERAL("|0|\0") }));
  241. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%.1x|", 0x0, 3, LITERAL("|0|\0") }));
  242. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%x|", 0x0, 3, LITERAL("|0|\0") }));
  243. EXPECT(test_single<int>({ LITERAL("xxxxx\0"), "|%#.1x|", 0x1, 5, LITERAL("|0x1|\0") }));
  244. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%x|", 0, 3, LITERAL("|0|\0") }));
  245. EXPECT(test_single<int>({ LITERAL("xxx\0"), "|%#x|", 0, 3, LITERAL("|0|\0") }));
  246. }
  247. TEST_CASE(inttypes_macros)
  248. {
  249. EXPECT(test_single<uint8_t>({ LITERAL("xxxxx"), "|%" PRIx8 "|", 0xAB, 4, LITERAL("|ab|\0") }));
  250. EXPECT(test_single<uint8_t>({ LITERAL("xxxxx"), "|%" PRIX8 "|", 0xAB, 4, LITERAL("|AB|\0") }));
  251. EXPECT(test_single<uint16_t>({ LITERAL("xxxxxxx"), "|%" PRIx16 "|", 0xC0DE, 6, LITERAL("|c0de|\0") }));
  252. EXPECT(test_single<uint16_t>({ LITERAL("xxxxxxx"), "|%" PRIX16 "|", 0xC0DE, 6, LITERAL("|C0DE|\0") }));
  253. }
  254. TEST_CASE(float_values)
  255. {
  256. union {
  257. float f;
  258. int i;
  259. } v;
  260. v.i = 0x7fc00000;
  261. EXPECT(test_single<double>({ LITERAL("xxxxxxx"), "|%4f|", v.f, 6, LITERAL("| nan|\0") }));
  262. EXPECT(test_single<double>({ LITERAL("xxxxxxx"), "|%4f|", -v.f, 6, LITERAL("|-nan|\0") }));
  263. v.i = 0x7f800000;
  264. EXPECT(test_single<double>({ LITERAL("xxxxxxx"), "|%4f|", v.f, 6, LITERAL("| inf|\0") }));
  265. EXPECT(test_single<double>({ LITERAL("xxxxxxx"), "|%4f|", -v.f, 6, LITERAL("|-inf|\0") }));
  266. }
  267. TEST_CASE(truncation)
  268. {
  269. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxxx"), "|%d|", INT_MAX, 12, LITERAL("|2147483647|\0") }));
  270. EXPECT(test_single<int>({ LITERAL("xxxxxxxxxxxxxx"), "|%d|", INT_MIN, 13, LITERAL("|-2147483648|\0") }));
  271. if constexpr (sizeof(long int) == 8) {
  272. EXPECT(test_single<long int>({ LITERAL("xxxxxxxxxxxxxxxxxxxxxx"), "|%ld|", LONG_MAX, 21, LITERAL("|9223372036854775807|\0") }));
  273. EXPECT(test_single<long int>({ LITERAL("xxxxxxxxxxxxxxxxxxxxxxx"), "|%ld|", LONG_MIN + 1, 22, LITERAL("|-9223372036854775807|\0") }));
  274. } else {
  275. EXPECT(test_single<long int>({ LITERAL("xxxxxxxxxxxxx"), "|%ld|", LONG_MAX, 12, LITERAL("|2147483647|\0") }));
  276. EXPECT(test_single<long int>({ LITERAL("xxxxxxxxxxxxxx"), "|%ld|", LONG_MIN, 13, LITERAL("|-2147483648|\0") }));
  277. }
  278. EXPECT(test_single<long long int>({ LITERAL("xxxxxxxxxxxxxxxxxxxxxx"), "|%lld|", LLONG_MAX, 21, LITERAL("|9223372036854775807|\0") }));
  279. EXPECT(test_single<long long int>({ LITERAL("xxxxxxxxxxxxxxxxxxxxxxx"), "|%lld|", LLONG_MIN + 1, 22, LITERAL("|-9223372036854775807|\0") }));
  280. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxxxx"), "|%u|", UINT_MAX, 12, LITERAL("|4294967295|\0") }));
  281. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxx"), "|%x|", UINT_MAX, 10, LITERAL("|ffffffff|\0") }));
  282. EXPECT(test_single<unsigned int>({ LITERAL("xxxxxxxxxxx"), "|%X|", UINT_MAX, 10, LITERAL("|FFFFFFFF|\0") }));
  283. if constexpr (sizeof(unsigned long int) == 8) {
  284. EXPECT(test_single<unsigned long int>({ LITERAL("xxxxxxxxxxxxxxxxxxxxxxx"), "|%lu|", ULONG_MAX, 22, LITERAL("|18446744073709551615|\0") }));
  285. EXPECT(test_single<unsigned long int>({ LITERAL("xxxxxxxxxxxxxxxxxxx"), "|%lx|", ULONG_MAX, 18, LITERAL("|ffffffffffffffff|\0") }));
  286. EXPECT(test_single<unsigned long int>({ LITERAL("xxxxxxxxxxxxxxxxxxx"), "|%lX|", ULONG_MAX, 18, LITERAL("|FFFFFFFFFFFFFFFF|\0") }));
  287. } else {
  288. EXPECT(test_single<unsigned long int>({ LITERAL("xxxxxxxxxxxxx"), "|%lu|", ULONG_MAX, 12, LITERAL("|4294967295|\0") }));
  289. EXPECT(test_single<unsigned long int>({ LITERAL("xxxxxxxxxxx"), "|%lx|", ULONG_MAX, 10, LITERAL("|ffffffff|\0") }));
  290. EXPECT(test_single<unsigned long int>({ LITERAL("xxxxxxxxxxx"), "|%lX|", ULONG_MAX, 10, LITERAL("|FFFFFFFF|\0") }));
  291. }
  292. EXPECT(test_single<unsigned long long int>({ LITERAL("xxxxxxxxxxxxxxxxxxxxxxx"), "|%llu|", ULLONG_MAX, 22, LITERAL("|18446744073709551615|\0") }));
  293. EXPECT(test_single<unsigned long long int>({ LITERAL("xxxxxxxxxxxxxxxxxxx"), "|%llx|", ULLONG_MAX, 18, LITERAL("|ffffffffffffffff|\0") }));
  294. EXPECT(test_single<unsigned long long int>({ LITERAL("xxxxxxxxxxxxxxxxxxx"), "|%llX|", ULLONG_MAX, 18, LITERAL("|FFFFFFFFFFFFFFFF|\0") }));
  295. }