Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(25)

Side by Side Diff: base/debug/format_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698