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