safe_sprintf_unittest.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757
  1. // Copyright 2013 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 "butil/strings/safe_sprintf.h"
  5. #include <stdio.h>
  6. #include <string.h>
  7. #include <limits>
  8. #include "butil/logging.h"
  9. #include "butil/memory/scoped_ptr.h"
  10. #include <gtest/gtest.h>
  11. // Death tests on Android are currently very flaky. No need to add more flaky
  12. // tests, as they just make it hard to spot real problems.
  13. // TODO(markus): See if the restrictions on Android can eventually be lifted.
  14. #if defined(GTEST_HAS_DEATH_TEST) && !defined(OS_ANDROID)
  15. #define ALLOW_DEATH_TEST
  16. #endif
  17. namespace butil {
  18. namespace strings {
  19. TEST(SafeSPrintfTest, Empty) {
  20. char buf[2] = { 'X', 'X' };
  21. // Negative buffer size should always result in an error.
  22. EXPECT_EQ(-1, SafeSNPrintf(buf, (size_t)-1, ""));
  23. EXPECT_EQ('X', buf[0]);
  24. EXPECT_EQ('X', buf[1]);
  25. // Zero buffer size should always result in an error.
  26. EXPECT_EQ(-1, SafeSNPrintf(buf, 0, ""));
  27. EXPECT_EQ('X', buf[0]);
  28. EXPECT_EQ('X', buf[1]);
  29. // A one-byte buffer should always print a single NUL byte.
  30. EXPECT_EQ(0, SafeSNPrintf(buf, 1, ""));
  31. EXPECT_EQ(0, buf[0]);
  32. EXPECT_EQ('X', buf[1]);
  33. buf[0] = 'X';
  34. // A larger buffer should leave the trailing bytes unchanged.
  35. EXPECT_EQ(0, SafeSNPrintf(buf, 2, ""));
  36. EXPECT_EQ(0, buf[0]);
  37. EXPECT_EQ('X', buf[1]);
  38. buf[0] = 'X';
  39. // The same test using SafeSPrintf() instead of SafeSNPrintf().
  40. EXPECT_EQ(0, SafeSPrintf(buf, ""));
  41. EXPECT_EQ(0, buf[0]);
  42. EXPECT_EQ('X', buf[1]);
  43. buf[0] = 'X';
  44. }
  45. TEST(SafeSPrintfTest, NoArguments) {
  46. // Output a text message that doesn't require any substitutions. This
  47. // is roughly equivalent to calling strncpy() (but unlike strncpy(), it does
  48. // always add a trailing NUL; it always deduplicates '%' characters).
  49. static const char text[] = "hello world";
  50. char ref[20], buf[20];
  51. memset(ref, 'X', sizeof(char) * arraysize(buf));
  52. memcpy(buf, ref, sizeof(buf));
  53. // A negative buffer size should always result in an error.
  54. EXPECT_EQ(-1, SafeSNPrintf(buf, (size_t)-1, text));
  55. EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
  56. // Zero buffer size should always result in an error.
  57. EXPECT_EQ(-1, SafeSNPrintf(buf, 0, text));
  58. EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
  59. // A one-byte buffer should always print a single NUL byte.
  60. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSNPrintf(buf, 1, text));
  61. EXPECT_EQ(0, buf[0]);
  62. EXPECT_TRUE(!memcmp(buf+1, ref+1, sizeof(buf)-1));
  63. memcpy(buf, ref, sizeof(buf));
  64. // A larger (but limited) buffer should always leave the trailing bytes
  65. // unchanged.
  66. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSNPrintf(buf, 2, text));
  67. EXPECT_EQ(text[0], buf[0]);
  68. EXPECT_EQ(0, buf[1]);
  69. EXPECT_TRUE(!memcmp(buf+2, ref+2, sizeof(buf)-2));
  70. memcpy(buf, ref, sizeof(buf));
  71. // A unrestricted buffer length should always leave the trailing bytes
  72. // unchanged.
  73. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
  74. SafeSNPrintf(buf, sizeof(buf), text));
  75. EXPECT_EQ(std::string(text), std::string(buf));
  76. EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
  77. sizeof(buf) - sizeof(text)));
  78. memcpy(buf, ref, sizeof(buf));
  79. // The same test using SafeSPrintf() instead of SafeSNPrintf().
  80. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSPrintf(buf, text));
  81. EXPECT_EQ(std::string(text), std::string(buf));
  82. EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
  83. sizeof(buf) - sizeof(text)));
  84. memcpy(buf, ref, sizeof(buf));
  85. // Check for deduplication of '%' percent characters.
  86. EXPECT_EQ(1, SafeSPrintf(buf, "%%"));
  87. EXPECT_EQ(2, SafeSPrintf(buf, "%%%%"));
  88. EXPECT_EQ(2, SafeSPrintf(buf, "%%X"));
  89. EXPECT_EQ(3, SafeSPrintf(buf, "%%%%X"));
  90. #if defined(NDEBUG)
  91. EXPECT_EQ(1, SafeSPrintf(buf, "%"));
  92. EXPECT_EQ(2, SafeSPrintf(buf, "%%%"));
  93. EXPECT_EQ(2, SafeSPrintf(buf, "%X"));
  94. EXPECT_EQ(3, SafeSPrintf(buf, "%%%X"));
  95. #elif defined(ALLOW_DEATH_TEST)
  96. EXPECT_DEATH(SafeSPrintf(buf, "%"), "src.1. == '%'");
  97. EXPECT_DEATH(SafeSPrintf(buf, "%%%"), "src.1. == '%'");
  98. EXPECT_DEATH(SafeSPrintf(buf, "%X"), "src.1. == '%'");
  99. EXPECT_DEATH(SafeSPrintf(buf, "%%%X"), "src.1. == '%'");
  100. #endif
  101. }
  102. TEST(SafeSPrintfTest, OneArgument) {
  103. // Test basic single-argument single-character substitution.
  104. const char text[] = "hello world";
  105. const char fmt[] = "hello%cworld";
  106. char ref[20], buf[20];
  107. memset(ref, 'X', sizeof(buf));
  108. memcpy(buf, ref, sizeof(buf));
  109. // A negative buffer size should always result in an error.
  110. EXPECT_EQ(-1, SafeSNPrintf(buf, (size_t)-1, fmt, ' '));
  111. EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
  112. // Zero buffer size should always result in an error.
  113. EXPECT_EQ(-1, SafeSNPrintf(buf, 0, fmt, ' '));
  114. EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
  115. // A one-byte buffer should always print a single NUL byte.
  116. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
  117. SafeSNPrintf(buf, 1, fmt, ' '));
  118. EXPECT_EQ(0, buf[0]);
  119. EXPECT_TRUE(!memcmp(buf+1, ref+1, sizeof(buf)-1));
  120. memcpy(buf, ref, sizeof(buf));
  121. // A larger (but limited) buffer should always leave the trailing bytes
  122. // unchanged.
  123. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
  124. SafeSNPrintf(buf, 2, fmt, ' '));
  125. EXPECT_EQ(text[0], buf[0]);
  126. EXPECT_EQ(0, buf[1]);
  127. EXPECT_TRUE(!memcmp(buf+2, ref+2, sizeof(buf)-2));
  128. memcpy(buf, ref, sizeof(buf));
  129. // A unrestricted buffer length should always leave the trailing bytes
  130. // unchanged.
  131. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
  132. SafeSNPrintf(buf, sizeof(buf), fmt, ' '));
  133. EXPECT_EQ(std::string(text), std::string(buf));
  134. EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
  135. sizeof(buf) - sizeof(text)));
  136. memcpy(buf, ref, sizeof(buf));
  137. // The same test using SafeSPrintf() instead of SafeSNPrintf().
  138. EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, SafeSPrintf(buf, fmt, ' '));
  139. EXPECT_EQ(std::string(text), std::string(buf));
  140. EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
  141. sizeof(buf) - sizeof(text)));
  142. memcpy(buf, ref, sizeof(buf));
  143. // Check for deduplication of '%' percent characters.
  144. EXPECT_EQ(1, SafeSPrintf(buf, "%%", 0));
  145. EXPECT_EQ(2, SafeSPrintf(buf, "%%%%", 0));
  146. EXPECT_EQ(2, SafeSPrintf(buf, "%Y", 0));
  147. EXPECT_EQ(2, SafeSPrintf(buf, "%%Y", 0));
  148. EXPECT_EQ(3, SafeSPrintf(buf, "%%%Y", 0));
  149. EXPECT_EQ(3, SafeSPrintf(buf, "%%%%Y", 0));
  150. #if defined(NDEBUG)
  151. EXPECT_EQ(1, SafeSPrintf(buf, "%", 0));
  152. EXPECT_EQ(2, SafeSPrintf(buf, "%%%", 0));
  153. #elif defined(ALLOW_DEATH_TEST)
  154. EXPECT_DEATH(SafeSPrintf(buf, "%", 0), "ch");
  155. EXPECT_DEATH(SafeSPrintf(buf, "%%%", 0), "ch");
  156. #endif
  157. }
  158. TEST(SafeSPrintfTest, MissingArg) {
  159. #if defined(NDEBUG)
  160. char buf[20];
  161. EXPECT_EQ(3, SafeSPrintf(buf, "%c%c", 'A'));
  162. EXPECT_EQ("A%c", std::string(buf));
  163. #elif defined(ALLOW_DEATH_TEST)
  164. char buf[20];
  165. EXPECT_DEATH(SafeSPrintf(buf, "%c%c", 'A'), "cur_arg < max_args");
  166. #endif
  167. }
  168. TEST(SafeSPrintfTest, ASANFriendlyBufferTest) {
  169. // Print into a buffer that is sized exactly to size. ASAN can verify that
  170. // nobody attempts to write past the end of the buffer.
  171. // There is a more complicated test in PrintLongString() that covers a lot
  172. // more edge case, but it is also harder to debug in case of a failure.
  173. const char kTestString[] = "This is a test";
  174. scoped_ptr<char[]> buf(new char[sizeof(kTestString)]);
  175. EXPECT_EQ(static_cast<ssize_t>(sizeof(kTestString) - 1),
  176. SafeSNPrintf(buf.get(), sizeof(kTestString), kTestString));
  177. EXPECT_EQ(std::string(kTestString), std::string(buf.get()));
  178. EXPECT_EQ(static_cast<ssize_t>(sizeof(kTestString) - 1),
  179. SafeSNPrintf(buf.get(), sizeof(kTestString), "%s", kTestString));
  180. EXPECT_EQ(std::string(kTestString), std::string(buf.get()));
  181. }
  182. TEST(SafeSPrintfTest, NArgs) {
  183. // Pre-C++11 compilers have a different code path, that can only print
  184. // up to ten distinct arguments.
  185. // We test both SafeSPrintf() and SafeSNPrintf(). This makes sure we don't
  186. // have typos in the copy-n-pasted code that is needed to deal with various
  187. // numbers of arguments.
  188. char buf[12];
  189. EXPECT_EQ(1, SafeSPrintf(buf, "%c", 1));
  190. EXPECT_EQ("\1", std::string(buf));
  191. EXPECT_EQ(2, SafeSPrintf(buf, "%c%c", 1, 2));
  192. EXPECT_EQ("\1\2", std::string(buf));
  193. EXPECT_EQ(3, SafeSPrintf(buf, "%c%c%c", 1, 2, 3));
  194. EXPECT_EQ("\1\2\3", std::string(buf));
  195. EXPECT_EQ(4, SafeSPrintf(buf, "%c%c%c%c", 1, 2, 3, 4));
  196. EXPECT_EQ("\1\2\3\4", std::string(buf));
  197. EXPECT_EQ(5, SafeSPrintf(buf, "%c%c%c%c%c", 1, 2, 3, 4, 5));
  198. EXPECT_EQ("\1\2\3\4\5", std::string(buf));
  199. EXPECT_EQ(6, SafeSPrintf(buf, "%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6));
  200. EXPECT_EQ("\1\2\3\4\5\6", std::string(buf));
  201. EXPECT_EQ(7, SafeSPrintf(buf, "%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7));
  202. EXPECT_EQ("\1\2\3\4\5\6\7", std::string(buf));
  203. EXPECT_EQ(8, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7, 8));
  204. EXPECT_EQ("\1\2\3\4\5\6\7\10", std::string(buf));
  205. EXPECT_EQ(9, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c%c",
  206. 1, 2, 3, 4, 5, 6, 7, 8, 9));
  207. EXPECT_EQ("\1\2\3\4\5\6\7\10\11", std::string(buf));
  208. EXPECT_EQ(10, SafeSPrintf(buf, "%c%c%c%c%c%c%c%c%c%c",
  209. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
  210. // Repeat all the tests with SafeSNPrintf() instead of SafeSPrintf().
  211. EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf));
  212. EXPECT_EQ(1, SafeSNPrintf(buf, 11, "%c", 1));
  213. EXPECT_EQ("\1", std::string(buf));
  214. EXPECT_EQ(2, SafeSNPrintf(buf, 11, "%c%c", 1, 2));
  215. EXPECT_EQ("\1\2", std::string(buf));
  216. EXPECT_EQ(3, SafeSNPrintf(buf, 11, "%c%c%c", 1, 2, 3));
  217. EXPECT_EQ("\1\2\3", std::string(buf));
  218. EXPECT_EQ(4, SafeSNPrintf(buf, 11, "%c%c%c%c", 1, 2, 3, 4));
  219. EXPECT_EQ("\1\2\3\4", std::string(buf));
  220. EXPECT_EQ(5, SafeSNPrintf(buf, 11, "%c%c%c%c%c", 1, 2, 3, 4, 5));
  221. EXPECT_EQ("\1\2\3\4\5", std::string(buf));
  222. EXPECT_EQ(6, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6));
  223. EXPECT_EQ("\1\2\3\4\5\6", std::string(buf));
  224. EXPECT_EQ(7, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7));
  225. EXPECT_EQ("\1\2\3\4\5\6\7", std::string(buf));
  226. EXPECT_EQ(8, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c",
  227. 1, 2, 3, 4, 5, 6, 7, 8));
  228. EXPECT_EQ("\1\2\3\4\5\6\7\10", std::string(buf));
  229. EXPECT_EQ(9, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c%c",
  230. 1, 2, 3, 4, 5, 6, 7, 8, 9));
  231. EXPECT_EQ("\1\2\3\4\5\6\7\10\11", std::string(buf));
  232. EXPECT_EQ(10, SafeSNPrintf(buf, 11, "%c%c%c%c%c%c%c%c%c%c",
  233. 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
  234. EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf));
  235. }
  236. TEST(SafeSPrintfTest, DataTypes) {
  237. char buf[40];
  238. // Bytes
  239. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint8_t)1));
  240. EXPECT_EQ("1", std::string(buf));
  241. EXPECT_EQ(3, SafeSPrintf(buf, "%d", (uint8_t)-1));
  242. EXPECT_EQ("255", std::string(buf));
  243. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int8_t)1));
  244. EXPECT_EQ("1", std::string(buf));
  245. EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int8_t)-1));
  246. EXPECT_EQ("-1", std::string(buf));
  247. EXPECT_EQ(4, SafeSPrintf(buf, "%d", (int8_t)-128));
  248. EXPECT_EQ("-128", std::string(buf));
  249. // Half-words
  250. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint16_t)1));
  251. EXPECT_EQ("1", std::string(buf));
  252. EXPECT_EQ(5, SafeSPrintf(buf, "%d", (uint16_t)-1));
  253. EXPECT_EQ("65535", std::string(buf));
  254. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int16_t)1));
  255. EXPECT_EQ("1", std::string(buf));
  256. EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int16_t)-1));
  257. EXPECT_EQ("-1", std::string(buf));
  258. EXPECT_EQ(6, SafeSPrintf(buf, "%d", (int16_t)-32768));
  259. EXPECT_EQ("-32768", std::string(buf));
  260. // Words
  261. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint32_t)1));
  262. EXPECT_EQ("1", std::string(buf));
  263. EXPECT_EQ(10, SafeSPrintf(buf, "%d", (uint32_t)-1));
  264. EXPECT_EQ("4294967295", std::string(buf));
  265. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int32_t)1));
  266. EXPECT_EQ("1", std::string(buf));
  267. EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int32_t)-1));
  268. EXPECT_EQ("-1", std::string(buf));
  269. // Work-around for an limitation of C90
  270. EXPECT_EQ(11, SafeSPrintf(buf, "%d", (int32_t)-2147483647-1));
  271. EXPECT_EQ("-2147483648", std::string(buf));
  272. // Quads
  273. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (uint64_t)1));
  274. EXPECT_EQ("1", std::string(buf));
  275. EXPECT_EQ(20, SafeSPrintf(buf, "%d", (uint64_t)-1));
  276. EXPECT_EQ("18446744073709551615", std::string(buf));
  277. EXPECT_EQ(1, SafeSPrintf(buf, "%d", (int64_t)1));
  278. EXPECT_EQ("1", std::string(buf));
  279. EXPECT_EQ(2, SafeSPrintf(buf, "%d", (int64_t)-1));
  280. EXPECT_EQ("-1", std::string(buf));
  281. // Work-around for an limitation of C90
  282. EXPECT_EQ(20, SafeSPrintf(buf, "%d", (int64_t)-9223372036854775807LL-1));
  283. EXPECT_EQ("-9223372036854775808", std::string(buf));
  284. // Strings (both const and mutable).
  285. EXPECT_EQ(4, SafeSPrintf(buf, "test"));
  286. EXPECT_EQ("test", std::string(buf));
  287. EXPECT_EQ(4, SafeSPrintf(buf, buf));
  288. EXPECT_EQ("test", std::string(buf));
  289. // Pointer
  290. char addr[20];
  291. sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf);
  292. SafeSPrintf(buf, "%p", buf);
  293. EXPECT_EQ(std::string(addr), std::string(buf));
  294. SafeSPrintf(buf, "%p", (const char *)buf);
  295. EXPECT_EQ(std::string(addr), std::string(buf));
  296. sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)sprintf);
  297. SafeSPrintf(buf, "%p", sprintf);
  298. EXPECT_EQ(std::string(addr), std::string(buf));
  299. // Padding for pointers is a little more complicated because of the "0x"
  300. // prefix. Padding with '0' zeros is relatively straight-forward, but
  301. // padding with ' ' spaces requires more effort.
  302. sprintf(addr, "0x%017llX", (unsigned long long)(uintptr_t)buf);
  303. SafeSPrintf(buf, "%019p", buf);
  304. EXPECT_EQ(std::string(addr), std::string(buf));
  305. sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf);
  306. memset(addr, ' ',
  307. (char*)memmove(addr + sizeof(addr) - strlen(addr) - 1,
  308. addr, strlen(addr)+1) - addr);
  309. SafeSPrintf(buf, "%19p", buf);
  310. EXPECT_EQ(std::string(addr), std::string(buf));
  311. }
  312. namespace {
  313. void PrintLongString(char* buf, size_t sz) {
  314. // Output a reasonably complex expression into a limited-size buffer.
  315. // At least one byte is available for writing the NUL character.
  316. CHECK_GT(sz, static_cast<size_t>(0));
  317. // Allocate slightly more space, so that we can verify that SafeSPrintf()
  318. // never writes past the end of the buffer.
  319. scoped_ptr<char[]> tmp(new char[sz+2]);
  320. memset(tmp.get(), 'X', sz+2);
  321. // Use SafeSPrintf() to output a complex list of arguments:
  322. // - test padding and truncating %c single characters.
  323. // - test truncating %s simple strings.
  324. // - test mismatching arguments and truncating (for %d != %s).
  325. // - test zero-padding and truncating %x hexadecimal numbers.
  326. // - test outputting and truncating %d MININT.
  327. // - test outputting and truncating %p arbitrary pointer values.
  328. // - test outputting, padding and truncating NULL-pointer %s strings.
  329. char* out = tmp.get();
  330. size_t out_sz = sz;
  331. size_t len;
  332. for (scoped_ptr<char[]> perfect_buf;;) {
  333. size_t needed = SafeSNPrintf(out, out_sz,
  334. #if defined(NDEBUG)
  335. "A%2cong %s: %d %010X %d %p%7s", 'l', "string", "",
  336. #else
  337. "A%2cong %s: %%d %010X %d %p%7s", 'l', "string",
  338. #endif
  339. 0xDEADBEEF, std::numeric_limits<intptr_t>::min(),
  340. PrintLongString, static_cast<char*>(NULL)) + 1;
  341. // Various sanity checks:
  342. // The numbered of characters needed to print the full string should always
  343. // be bigger or equal to the bytes that have actually been output.
  344. len = strlen(tmp.get());
  345. CHECK_GE(needed, len+1);
  346. // The number of characters output should always fit into the buffer that
  347. // was passed into SafeSPrintf().
  348. CHECK_LT(len, out_sz);
  349. // The output is always terminated with a NUL byte (actually, this test is
  350. // always going to pass, as strlen() already verified this)
  351. EXPECT_FALSE(tmp[len]);
  352. // ASAN can check that we are not overwriting buffers, iff we make sure the
  353. // buffer is exactly the size that we are expecting to be written. After
  354. // running SafeSNPrintf() the first time, it is possible to compute the
  355. // correct buffer size for this test. So, allocate a second buffer and run
  356. // the exact same SafeSNPrintf() command again.
  357. if (!perfect_buf.get()) {
  358. out_sz = std::min(needed, sz);
  359. out = new char[out_sz];
  360. perfect_buf.reset(out);
  361. } else {
  362. break;
  363. }
  364. }
  365. // All trailing bytes are unchanged.
  366. for (size_t i = len+1; i < sz+2; ++i)
  367. EXPECT_EQ('X', tmp[i]);
  368. // The text that was generated by SafeSPrintf() should always match the
  369. // equivalent text generated by sprintf(). Please note that the format
  370. // string for sprintf() is not complicated, as it does not have the
  371. // benefit of getting type information from the C++ compiler.
  372. //
  373. // N.B.: It would be so much cleaner to use snprintf(). But unfortunately,
  374. // Visual Studio doesn't support this function, and the work-arounds
  375. // are all really awkward.
  376. char ref[256];
  377. CHECK_LE(sz, sizeof(ref));
  378. sprintf(ref, "A long string: %%d 00DEADBEEF %lld 0x%llX <NULL>",
  379. static_cast<long long>(std::numeric_limits<intptr_t>::min()),
  380. static_cast<unsigned long long>(
  381. reinterpret_cast<uintptr_t>(PrintLongString)));
  382. ref[sz-1] = '\000';
  383. #if defined(NDEBUG)
  384. const size_t kSSizeMax = std::numeric_limits<ssize_t>::max();
  385. #else
  386. const size_t kSSizeMax = internal::GetSafeSPrintfSSizeMaxForTest();
  387. #endif
  388. // Compare the output from SafeSPrintf() to the one from sprintf().
  389. EXPECT_EQ(std::string(ref).substr(0, kSSizeMax-1), std::string(tmp.get()));
  390. // We allocated a slightly larger buffer, so that we could perform some
  391. // extra sanity checks. Now that the tests have all passed, we copy the
  392. // data to the output buffer that the caller provided.
  393. memcpy(buf, tmp.get(), len+1);
  394. }
  395. #if !defined(NDEBUG)
  396. class ScopedSafeSPrintfSSizeMaxSetter {
  397. public:
  398. ScopedSafeSPrintfSSizeMaxSetter(size_t sz) {
  399. old_ssize_max_ = internal::GetSafeSPrintfSSizeMaxForTest();
  400. internal::SetSafeSPrintfSSizeMaxForTest(sz);
  401. }
  402. ~ScopedSafeSPrintfSSizeMaxSetter() {
  403. internal::SetSafeSPrintfSSizeMaxForTest(old_ssize_max_);
  404. }
  405. private:
  406. size_t old_ssize_max_;
  407. DISALLOW_COPY_AND_ASSIGN(ScopedSafeSPrintfSSizeMaxSetter);
  408. };
  409. #endif
  410. } // anonymous namespace
  411. TEST(SafeSPrintfTest, Truncation) {
  412. // We use PrintLongString() to print a complex long string and then
  413. // truncate to all possible lengths. This ends up exercising a lot of
  414. // different code paths in SafeSPrintf() and IToASCII(), as truncation can
  415. // happen in a lot of different states.
  416. char ref[256];
  417. PrintLongString(ref, sizeof(ref));
  418. for (size_t i = strlen(ref)+1; i; --i) {
  419. char buf[sizeof(ref)];
  420. PrintLongString(buf, i);
  421. EXPECT_EQ(std::string(ref, i - 1), std::string(buf));
  422. }
  423. // When compiling in debug mode, we have the ability to fake a small
  424. // upper limit for the maximum value that can be stored in an ssize_t.
  425. // SafeSPrintf() uses this upper limit to determine how many bytes it will
  426. // write to the buffer, even if the caller claimed a bigger buffer size.
  427. // Repeat the truncation test and verify that this other code path in
  428. // SafeSPrintf() works correctly, too.
  429. #if !defined(NDEBUG)
  430. for (size_t i = strlen(ref)+1; i > 1; --i) {
  431. ScopedSafeSPrintfSSizeMaxSetter ssize_max_setter(i);
  432. char buf[sizeof(ref)];
  433. PrintLongString(buf, sizeof(buf));
  434. EXPECT_EQ(std::string(ref, i - 1), std::string(buf));
  435. }
  436. // kSSizeMax is also used to constrain the maximum amount of padding, before
  437. // SafeSPrintf() detects an error in the format string.
  438. ScopedSafeSPrintfSSizeMaxSetter ssize_max_setter(100);
  439. char buf[256];
  440. EXPECT_EQ(99, SafeSPrintf(buf, "%99c", ' '));
  441. EXPECT_EQ(std::string(99, ' '), std::string(buf));
  442. *buf = '\000';
  443. #if defined(ALLOW_DEATH_TEST)
  444. EXPECT_DEATH(SafeSPrintf(buf, "%100c", ' '), "padding <= max_padding");
  445. #endif
  446. EXPECT_EQ(0, *buf);
  447. #endif
  448. }
  449. TEST(SafeSPrintfTest, Padding) {
  450. char buf[40], fmt[40];
  451. // Chars %c
  452. EXPECT_EQ(1, SafeSPrintf(buf, "%c", 'A'));
  453. EXPECT_EQ("A", std::string(buf));
  454. EXPECT_EQ(2, SafeSPrintf(buf, "%2c", 'A'));
  455. EXPECT_EQ(" A", std::string(buf));
  456. EXPECT_EQ(2, SafeSPrintf(buf, "%02c", 'A'));
  457. EXPECT_EQ(" A", std::string(buf));
  458. EXPECT_EQ(4, SafeSPrintf(buf, "%-2c", 'A'));
  459. EXPECT_EQ("%-2c", std::string(buf));
  460. SafeSPrintf(fmt, "%%%dc", std::numeric_limits<ssize_t>::max() - 1);
  461. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, SafeSPrintf(buf, fmt, 'A'));
  462. SafeSPrintf(fmt, "%%%dc",
  463. static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  464. #if defined(NDEBUG)
  465. EXPECT_EQ(2, SafeSPrintf(buf, fmt, 'A'));
  466. EXPECT_EQ("%c", std::string(buf));
  467. #elif defined(ALLOW_DEATH_TEST)
  468. EXPECT_DEATH(SafeSPrintf(buf, fmt, 'A'), "padding <= max_padding");
  469. #endif
  470. // Octal %o
  471. EXPECT_EQ(1, SafeSPrintf(buf, "%o", 1));
  472. EXPECT_EQ("1", std::string(buf));
  473. EXPECT_EQ(2, SafeSPrintf(buf, "%2o", 1));
  474. EXPECT_EQ(" 1", std::string(buf));
  475. EXPECT_EQ(2, SafeSPrintf(buf, "%02o", 1));
  476. EXPECT_EQ("01", std::string(buf));
  477. EXPECT_EQ(12, SafeSPrintf(buf, "%12o", -1));
  478. EXPECT_EQ(" 37777777777", std::string(buf));
  479. EXPECT_EQ(12, SafeSPrintf(buf, "%012o", -1));
  480. EXPECT_EQ("037777777777", std::string(buf));
  481. EXPECT_EQ(23, SafeSPrintf(buf, "%23o", -1LL));
  482. EXPECT_EQ(" 1777777777777777777777", std::string(buf));
  483. EXPECT_EQ(23, SafeSPrintf(buf, "%023o", -1LL));
  484. EXPECT_EQ("01777777777777777777777", std::string(buf));
  485. EXPECT_EQ(3, SafeSPrintf(buf, "%2o", 0111));
  486. EXPECT_EQ("111", std::string(buf));
  487. EXPECT_EQ(4, SafeSPrintf(buf, "%-2o", 1));
  488. EXPECT_EQ("%-2o", std::string(buf));
  489. SafeSPrintf(fmt, "%%%do", std::numeric_limits<ssize_t>::max()-1);
  490. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  491. SafeSNPrintf(buf, 4, fmt, 1));
  492. EXPECT_EQ(" ", std::string(buf));
  493. SafeSPrintf(fmt, "%%0%do", std::numeric_limits<ssize_t>::max()-1);
  494. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  495. SafeSNPrintf(buf, 4, fmt, 1));
  496. EXPECT_EQ("000", std::string(buf));
  497. SafeSPrintf(fmt, "%%%do",
  498. static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  499. #if defined(NDEBUG)
  500. EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1));
  501. EXPECT_EQ("%o", std::string(buf));
  502. #elif defined(ALLOW_DEATH_TEST)
  503. EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding");
  504. #endif
  505. // Decimals %d
  506. EXPECT_EQ(1, SafeSPrintf(buf, "%d", 1));
  507. EXPECT_EQ("1", std::string(buf));
  508. EXPECT_EQ(2, SafeSPrintf(buf, "%2d", 1));
  509. EXPECT_EQ(" 1", std::string(buf));
  510. EXPECT_EQ(2, SafeSPrintf(buf, "%02d", 1));
  511. EXPECT_EQ("01", std::string(buf));
  512. EXPECT_EQ(3, SafeSPrintf(buf, "%3d", -1));
  513. EXPECT_EQ(" -1", std::string(buf));
  514. EXPECT_EQ(3, SafeSPrintf(buf, "%03d", -1));
  515. EXPECT_EQ("-01", std::string(buf));
  516. EXPECT_EQ(3, SafeSPrintf(buf, "%2d", 111));
  517. EXPECT_EQ("111", std::string(buf));
  518. EXPECT_EQ(4, SafeSPrintf(buf, "%2d", -111));
  519. EXPECT_EQ("-111", std::string(buf));
  520. EXPECT_EQ(4, SafeSPrintf(buf, "%-2d", 1));
  521. EXPECT_EQ("%-2d", std::string(buf));
  522. SafeSPrintf(fmt, "%%%dd", std::numeric_limits<ssize_t>::max()-1);
  523. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  524. SafeSNPrintf(buf, 4, fmt, 1));
  525. EXPECT_EQ(" ", std::string(buf));
  526. SafeSPrintf(fmt, "%%0%dd", std::numeric_limits<ssize_t>::max()-1);
  527. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  528. SafeSNPrintf(buf, 4, fmt, 1));
  529. EXPECT_EQ("000", std::string(buf));
  530. SafeSPrintf(fmt, "%%%dd",
  531. static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  532. #if defined(NDEBUG)
  533. EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1));
  534. EXPECT_EQ("%d", std::string(buf));
  535. #elif defined(ALLOW_DEATH_TEST)
  536. EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding");
  537. #endif
  538. // Hex %X
  539. EXPECT_EQ(1, SafeSPrintf(buf, "%X", 1));
  540. EXPECT_EQ("1", std::string(buf));
  541. EXPECT_EQ(2, SafeSPrintf(buf, "%2X", 1));
  542. EXPECT_EQ(" 1", std::string(buf));
  543. EXPECT_EQ(2, SafeSPrintf(buf, "%02X", 1));
  544. EXPECT_EQ("01", std::string(buf));
  545. EXPECT_EQ(9, SafeSPrintf(buf, "%9X", -1));
  546. EXPECT_EQ(" FFFFFFFF", std::string(buf));
  547. EXPECT_EQ(9, SafeSPrintf(buf, "%09X", -1));
  548. EXPECT_EQ("0FFFFFFFF", std::string(buf));
  549. EXPECT_EQ(17, SafeSPrintf(buf, "%17X", -1LL));
  550. EXPECT_EQ(" FFFFFFFFFFFFFFFF", std::string(buf));
  551. EXPECT_EQ(17, SafeSPrintf(buf, "%017X", -1LL));
  552. EXPECT_EQ("0FFFFFFFFFFFFFFFF", std::string(buf));
  553. EXPECT_EQ(3, SafeSPrintf(buf, "%2X", 0x111));
  554. EXPECT_EQ("111", std::string(buf));
  555. EXPECT_EQ(4, SafeSPrintf(buf, "%-2X", 1));
  556. EXPECT_EQ("%-2X", std::string(buf));
  557. SafeSPrintf(fmt, "%%%dX", std::numeric_limits<ssize_t>::max()-1);
  558. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  559. SafeSNPrintf(buf, 4, fmt, 1));
  560. EXPECT_EQ(" ", std::string(buf));
  561. SafeSPrintf(fmt, "%%0%dX", std::numeric_limits<ssize_t>::max()-1);
  562. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  563. SafeSNPrintf(buf, 4, fmt, 1));
  564. EXPECT_EQ("000", std::string(buf));
  565. SafeSPrintf(fmt, "%%%dX",
  566. static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  567. #if defined(NDEBUG)
  568. EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1));
  569. EXPECT_EQ("%X", std::string(buf));
  570. #elif defined(ALLOW_DEATH_TEST)
  571. EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding");
  572. #endif
  573. // Pointer %p
  574. EXPECT_EQ(3, SafeSPrintf(buf, "%p", (void*)1));
  575. EXPECT_EQ("0x1", std::string(buf));
  576. EXPECT_EQ(4, SafeSPrintf(buf, "%4p", (void*)1));
  577. EXPECT_EQ(" 0x1", std::string(buf));
  578. EXPECT_EQ(4, SafeSPrintf(buf, "%04p", (void*)1));
  579. EXPECT_EQ("0x01", std::string(buf));
  580. EXPECT_EQ(5, SafeSPrintf(buf, "%4p", (void*)0x111));
  581. EXPECT_EQ("0x111", std::string(buf));
  582. EXPECT_EQ(4, SafeSPrintf(buf, "%-2p", (void*)1));
  583. EXPECT_EQ("%-2p", std::string(buf));
  584. SafeSPrintf(fmt, "%%%dp", std::numeric_limits<ssize_t>::max()-1);
  585. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  586. SafeSNPrintf(buf, 4, fmt, (void*)1));
  587. EXPECT_EQ(" ", std::string(buf));
  588. SafeSPrintf(fmt, "%%0%dp", std::numeric_limits<ssize_t>::max()-1);
  589. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  590. SafeSNPrintf(buf, 4, fmt, (void*)1));
  591. EXPECT_EQ("0x0", std::string(buf));
  592. SafeSPrintf(fmt, "%%%dp",
  593. static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  594. #if defined(NDEBUG)
  595. EXPECT_EQ(2, SafeSPrintf(buf, fmt, 1));
  596. EXPECT_EQ("%p", std::string(buf));
  597. #elif defined(ALLOW_DEATH_TEST)
  598. EXPECT_DEATH(SafeSPrintf(buf, fmt, 1), "padding <= max_padding");
  599. #endif
  600. // String
  601. EXPECT_EQ(1, SafeSPrintf(buf, "%s", "A"));
  602. EXPECT_EQ("A", std::string(buf));
  603. EXPECT_EQ(2, SafeSPrintf(buf, "%2s", "A"));
  604. EXPECT_EQ(" A", std::string(buf));
  605. EXPECT_EQ(2, SafeSPrintf(buf, "%02s", "A"));
  606. EXPECT_EQ(" A", std::string(buf));
  607. EXPECT_EQ(3, SafeSPrintf(buf, "%2s", "AAA"));
  608. EXPECT_EQ("AAA", std::string(buf));
  609. EXPECT_EQ(4, SafeSPrintf(buf, "%-2s", "A"));
  610. EXPECT_EQ("%-2s", std::string(buf));
  611. SafeSPrintf(fmt, "%%%ds", std::numeric_limits<ssize_t>::max()-1);
  612. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  613. SafeSNPrintf(buf, 4, fmt, "A"));
  614. EXPECT_EQ(" ", std::string(buf));
  615. SafeSPrintf(fmt, "%%0%ds", std::numeric_limits<ssize_t>::max()-1);
  616. EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
  617. SafeSNPrintf(buf, 4, fmt, "A"));
  618. EXPECT_EQ(" ", std::string(buf));
  619. SafeSPrintf(fmt, "%%%ds",
  620. static_cast<size_t>(std::numeric_limits<ssize_t>::max()));
  621. #if defined(NDEBUG)
  622. EXPECT_EQ(2, SafeSPrintf(buf, fmt, "A"));
  623. EXPECT_EQ("%s", std::string(buf));
  624. #elif defined(ALLOW_DEATH_TEST)
  625. EXPECT_DEATH(SafeSPrintf(buf, fmt, "A"), "padding <= max_padding");
  626. #endif
  627. }
  628. TEST(SafeSPrintfTest, EmbeddedNul) {
  629. char buf[] = { 'X', 'X', 'X', 'X' };
  630. EXPECT_EQ(2, SafeSPrintf(buf, "%3c", 0));
  631. EXPECT_EQ(' ', buf[0]);
  632. EXPECT_EQ(' ', buf[1]);
  633. EXPECT_EQ(0, buf[2]);
  634. EXPECT_EQ('X', buf[3]);
  635. // Check handling of a NUL format character. N.B. this takes two different
  636. // code paths depending on whether we are actually passing arguments. If
  637. // we don't have any arguments, we are running in the fast-path code, that
  638. // looks (almost) like a strncpy().
  639. #if defined(NDEBUG)
  640. EXPECT_EQ(2, SafeSPrintf(buf, "%%%"));
  641. EXPECT_EQ("%%", std::string(buf));
  642. EXPECT_EQ(2, SafeSPrintf(buf, "%%%", 0));
  643. EXPECT_EQ("%%", std::string(buf));
  644. #elif defined(ALLOW_DEATH_TEST)
  645. EXPECT_DEATH(SafeSPrintf(buf, "%%%"), "src.1. == '%'");
  646. EXPECT_DEATH(SafeSPrintf(buf, "%%%", 0), "ch");
  647. #endif
  648. }
  649. TEST(SafeSPrintfTest, EmitNULL) {
  650. #if defined(__GNUC__) && __GNUC__ >= 4
  651. #pragma GCC diagnostic push
  652. #pragma GCC diagnostic ignored "-Wconversion-null"
  653. #endif
  654. // NOTE(gejun): Warning in gcc 3.4
  655. #if !defined(__GNUC__) || __GNUC__ >= 4
  656. char buf[40];
  657. EXPECT_EQ(1, SafeSPrintf(buf, "%d", NULL));
  658. EXPECT_EQ("0", std::string(buf));
  659. EXPECT_EQ(3, SafeSPrintf(buf, "%p", NULL));
  660. EXPECT_EQ("0x0", std::string(buf));
  661. EXPECT_EQ(6, SafeSPrintf(buf, "%s", NULL));
  662. EXPECT_EQ("<NULL>", std::string(buf));
  663. #endif
  664. #if defined(__GNUC__) && __GNUC__ >= 4
  665. #pragma GCC diagnostic pop
  666. #endif
  667. }
  668. TEST(SafeSPrintfTest, PointerSize) {
  669. // The internal data representation is a 64bit value, independent of the
  670. // native word size. We want to perform sign-extension for signed integers,
  671. // but we want to avoid doing so for pointer types. This could be a
  672. // problem on systems, where pointers are only 32bit. This tests verifies
  673. // that there is no such problem.
  674. char *str = reinterpret_cast<char *>(0x80000000u);
  675. void *ptr = str;
  676. char buf[40];
  677. EXPECT_EQ(10, SafeSPrintf(buf, "%p", str));
  678. EXPECT_EQ("0x80000000", std::string(buf));
  679. EXPECT_EQ(10, SafeSPrintf(buf, "%p", ptr));
  680. EXPECT_EQ("0x80000000", std::string(buf));
  681. }
  682. } // namespace strings
  683. } // namespace butil