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