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

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: Addressed Jeffrey's comments 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
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 base {
17 namespace debug {
18
19 TEST(FormatTest, Empty) {
20 char buf[2] = { 'X', 'X' };
21
22 // Negative buffer size should always result in an error.
23 EXPECT_EQ(-1, FormatN(buf, -1, ""));
24 EXPECT_EQ('X', buf[0]);
25 EXPECT_EQ('X', buf[1]);
26
27 // Zero buffer size should always result in an error.
28 EXPECT_EQ(-1, FormatN(buf, 0, ""));
29 EXPECT_EQ('X', buf[0]);
30 EXPECT_EQ('X', buf[1]);
31
32 // A one-byte buffer should always print a single NUL byte.
33 EXPECT_EQ(0, FormatN(buf, 1, ""));
34 EXPECT_EQ(0, buf[0]);
35 EXPECT_EQ('X', buf[1]);
36 buf[0] = 'X';
37
38 // A larger buffer should leave the trailing bytes unchanged.
39 EXPECT_EQ(0, FormatN(buf, 2, ""));
40 EXPECT_EQ(0, buf[0]);
41 EXPECT_EQ('X', buf[1]);
42 buf[0] = 'X';
43
44 // The same test using Format() instead of FormatN().
45 EXPECT_EQ(0, Format(buf, ""));
46 EXPECT_EQ(0, buf[0]);
47 EXPECT_EQ('X', buf[1]);
48 buf[0] = 'X';
49 }
50
51 TEST(FormatTest, NoArguments) {
52 // Output a text message that doesn't require any substitutions. This
53 // is roughly equivalent to calling strncpy() (but unlike strncpy(), it does
54 // always add a trailing NUL; it always deduplicates '%' characters).
55 const char text[] = "hello world";
56 char ref[20], buf[20];
57 memset(ref, 'X', sizeof(buf));
58 memcpy(buf, ref, sizeof(buf));
59
60 // A negative buffer size should always result in an error.
61 EXPECT_EQ(-1, FormatN(buf, -1, text));
62 EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
63
64 // Zero buffer size should always result in an error.
65 EXPECT_EQ(-1, FormatN(buf, 0, text));
66 EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
67
68 // A one-byte buffer should always print a single NUL byte.
69 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, FormatN(buf, 1, text));
70 EXPECT_EQ(0, buf[0]);
71 EXPECT_TRUE(!memcmp(buf+1, ref+1, sizeof(buf)-1));
72 memcpy(buf, ref, sizeof(buf));
73
74 // A larger (but limited) buffer should always leave the trailing bytes
75 // unchanged.
76 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, FormatN(buf, 2, text));
77 EXPECT_EQ(text[0], buf[0]);
78 EXPECT_EQ(0, buf[1]);
79 EXPECT_TRUE(!memcmp(buf+2, ref+2, sizeof(buf)-2));
80 memcpy(buf, ref, sizeof(buf));
81
82 // A unrestricted buffer length should always leave the trailing bytes
83 // unchanged.
84 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
85 FormatN(buf, sizeof(buf), text));
86 EXPECT_EQ(std::string(text), std::string(buf));
87 EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
88 sizeof(buf) - sizeof(text)));
89 memcpy(buf, ref, sizeof(buf));
90
91 // The same test using Format() instead of FormatN().
92 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, Format(buf, text));
93 EXPECT_EQ(std::string(text), std::string(buf));
94 EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
95 sizeof(buf) - sizeof(text)));
96 memcpy(buf, ref, sizeof(buf));
97
98 // Check for deduplication of '%' percent characters.
99 EXPECT_EQ(1, Format(buf, "%"));
100 EXPECT_EQ(1, Format(buf, "%%"));
101 EXPECT_EQ(2, Format(buf, "%%%"));
102 EXPECT_EQ(2, Format(buf, "%%%%"));
103 EXPECT_EQ(2, Format(buf, "%X"));
104 EXPECT_EQ(2, Format(buf, "%%X"));
105 EXPECT_EQ(3, Format(buf, "%%%X"));
106 EXPECT_EQ(3, Format(buf, "%%%%X"));
107 }
108
109 TEST(FormatTest, OneArgument) {
110 // Test basic single-argument single-character substitution.
111 const char text[] = "hello world";
112 const char fmt[] = "hello%cworld";
113 char ref[20], buf[20];
114 memset(ref, 'X', sizeof(buf));
115 memcpy(buf, ref, sizeof(buf));
116
117 // A negative buffer size should always result in an error.
118 EXPECT_EQ(-1, FormatN(buf, -1, fmt, ' '));
119 EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
120
121 // Zero buffer size should always result in an error.
122 EXPECT_EQ(-1, FormatN(buf, 0, fmt, ' '));
123 EXPECT_TRUE(!memcmp(buf, ref, sizeof(buf)));
124
125 // A one-byte buffer should always print a single NUL byte.
126 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, FormatN(buf, 1, fmt, ' '));
127 EXPECT_EQ(0, buf[0]);
128 EXPECT_TRUE(!memcmp(buf+1, ref+1, sizeof(buf)-1));
129 memcpy(buf, ref, sizeof(buf));
130
131 // A larger (but limited) buffer should always leave the trailing bytes
132 // unchanged.
133 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, FormatN(buf, 2, fmt, ' '));
134 EXPECT_EQ(text[0], buf[0]);
135 EXPECT_EQ(0, buf[1]);
136 EXPECT_TRUE(!memcmp(buf+2, ref+2, sizeof(buf)-2));
137 memcpy(buf, ref, sizeof(buf));
138
139 // A unrestricted buffer length should always leave the trailing bytes
140 // unchanged.
141 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1,
142 FormatN(buf, sizeof(buf), fmt, ' '));
143 EXPECT_EQ(std::string(text), std::string(buf));
144 EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
145 sizeof(buf) - sizeof(text)));
146 memcpy(buf, ref, sizeof(buf));
147
148 // The same test using Format() instead of FormatN().
149 EXPECT_EQ(static_cast<ssize_t>(sizeof(text))-1, Format(buf, fmt, ' '));
150 EXPECT_EQ(std::string(text), std::string(buf));
151 EXPECT_TRUE(!memcmp(buf + sizeof(text), ref + sizeof(text),
152 sizeof(buf) - sizeof(text)));
153 memcpy(buf, ref, sizeof(buf));
154
155 // Check for deduplication of '%' percent characters.
156 EXPECT_EQ(1, Format(buf, "%", 0));
157 EXPECT_EQ(1, Format(buf, "%%", 0));
158 EXPECT_EQ(2, Format(buf, "%%%", 0));
159 EXPECT_EQ(2, Format(buf, "%%%%", 0));
160 EXPECT_EQ(2, Format(buf, "%Y", 0));
161 EXPECT_EQ(2, Format(buf, "%%Y", 0));
162 EXPECT_EQ(3, Format(buf, "%%%Y", 0));
163 EXPECT_EQ(3, Format(buf, "%%%%Y", 0));
164 }
165
166 #ifdef NDEBUG
167 TEST(FormatTest, MissingArg) {
168 char buf[20];
169 EXPECT_EQ(3, Format(buf, "%c%c", 'A'));
170 EXPECT_EQ("A%c", std::string(buf));
171 }
172 #endif
173
174 TEST(FormatTest, NArgs) {
175 // Pre-C++11 compilers have a different code path, that can only print
176 // up to ten distinct arguments.
177 // We test both Format() and FormatN(). This makes sure we don't have
178 // typos in the copy-n-pasted code that is needed to deal with various
179 // numbers of arguments.
180 char buf[12];
181 EXPECT_EQ(1, Format(buf, "%c", 1));
182 EXPECT_EQ("\1", std::string(buf));
183 EXPECT_EQ(2, Format(buf, "%c%c", 1, 2));
184 EXPECT_EQ("\1\2", std::string(buf));
185 EXPECT_EQ(3, Format(buf, "%c%c%c", 1, 2, 3));
186 EXPECT_EQ("\1\2\3", std::string(buf));
187 EXPECT_EQ(4, Format(buf, "%c%c%c%c", 1, 2, 3, 4));
188 EXPECT_EQ("\1\2\3\4", std::string(buf));
189 EXPECT_EQ(5, Format(buf, "%c%c%c%c%c", 1, 2, 3, 4, 5));
190 EXPECT_EQ("\1\2\3\4\5", std::string(buf));
191 EXPECT_EQ(6, Format(buf, "%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6));
192 EXPECT_EQ("\1\2\3\4\5\6", std::string(buf));
193 EXPECT_EQ(7, Format(buf, "%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7));
194 EXPECT_EQ("\1\2\3\4\5\6\7", std::string(buf));
195 EXPECT_EQ(8, Format(buf, "%c%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7, 8));
196 EXPECT_EQ("\1\2\3\4\5\6\7\10", std::string(buf));
197 EXPECT_EQ(9, Format(buf, "%c%c%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7, 8, 9));
198 EXPECT_EQ("\1\2\3\4\5\6\7\10\11", std::string(buf));
199 EXPECT_EQ(10, Format(buf, "%c%c%c%c%c%c%c%c%c%c",
200 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
201
202 // Repeat all the tests with FormatN() instead of Format().
203 EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf));
204 EXPECT_EQ(1, FormatN(buf, 11, "%c", 1));
205 EXPECT_EQ("\1", std::string(buf));
206 EXPECT_EQ(2, FormatN(buf, 11, "%c%c", 1, 2));
207 EXPECT_EQ("\1\2", std::string(buf));
208 EXPECT_EQ(3, FormatN(buf, 11, "%c%c%c", 1, 2, 3));
209 EXPECT_EQ("\1\2\3", std::string(buf));
210 EXPECT_EQ(4, FormatN(buf, 11, "%c%c%c%c", 1, 2, 3, 4));
211 EXPECT_EQ("\1\2\3\4", std::string(buf));
212 EXPECT_EQ(5, FormatN(buf, 11, "%c%c%c%c%c", 1, 2, 3, 4, 5));
213 EXPECT_EQ("\1\2\3\4\5", std::string(buf));
214 EXPECT_EQ(6, FormatN(buf, 11, "%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6));
215 EXPECT_EQ("\1\2\3\4\5\6", std::string(buf));
216 EXPECT_EQ(7, FormatN(buf, 11, "%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7));
217 EXPECT_EQ("\1\2\3\4\5\6\7", std::string(buf));
218 EXPECT_EQ(8, FormatN(buf, 11, "%c%c%c%c%c%c%c%c", 1, 2, 3, 4, 5, 6, 7, 8));
219 EXPECT_EQ("\1\2\3\4\5\6\7\10", std::string(buf));
220 EXPECT_EQ(9, FormatN(buf, 11, "%c%c%c%c%c%c%c%c%c",
221 1, 2, 3, 4, 5, 6, 7, 8, 9));
222 EXPECT_EQ("\1\2\3\4\5\6\7\10\11", std::string(buf));
223 EXPECT_EQ(10, FormatN(buf, 11, "%c%c%c%c%c%c%c%c%c%c",
224 1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
225 EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12", std::string(buf));
226
227
228 // C++11 is smart enough to handle variadic template arguments. It can
229 // deal with arbitrary numbers of arguments.
230 #if __cplusplus >= 201103 // C++11
231 EXPECT_EQ(11, Format(buf, "%c%c%c%c%c%c%c%c%c%c%c",
232 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
233 EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12\13", std::string(buf));
234 EXPECT_EQ(11, FormatN(buf, 12, "%c%c%c%c%c%c%c%c%c%c%c",
235 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11));
236 EXPECT_EQ("\1\2\3\4\5\6\7\10\11\12\13", std::string(buf));
237 #endif
238 }
239
240 TEST(FormatTest, DataTypes) {
241 char buf[40];
242
243 // Bytes
244 EXPECT_EQ(1, Format(buf, "%d", (uint8_t)1));
245 EXPECT_EQ("1", std::string(buf));
246 EXPECT_EQ(3, Format(buf, "%d", (uint8_t)-1));
247 EXPECT_EQ("255", std::string(buf));
248 EXPECT_EQ(1, Format(buf, "%d", (int8_t)1));
249 EXPECT_EQ("1", std::string(buf));
250 EXPECT_EQ(2, Format(buf, "%d", (int8_t)-1));
251 EXPECT_EQ("-1", std::string(buf));
252 EXPECT_EQ(4, Format(buf, "%d", (int8_t)-128));
253 EXPECT_EQ("-128", std::string(buf));
254
255 // Half-words
256 EXPECT_EQ(1, Format(buf, "%d", (uint16_t)1));
257 EXPECT_EQ("1", std::string(buf));
258 EXPECT_EQ(5, Format(buf, "%d", (uint16_t)-1));
259 EXPECT_EQ("65535", std::string(buf));
260 EXPECT_EQ(1, Format(buf, "%d", (int16_t)1));
261 EXPECT_EQ("1", std::string(buf));
262 EXPECT_EQ(2, Format(buf, "%d", (int16_t)-1));
263 EXPECT_EQ("-1", std::string(buf));
264 EXPECT_EQ(6, Format(buf, "%d", (int16_t)-32768));
265 EXPECT_EQ("-32768", std::string(buf));
266
267 // Words
268 EXPECT_EQ(1, Format(buf, "%d", (uint32_t)1));
269 EXPECT_EQ("1", std::string(buf));
270 EXPECT_EQ(10, Format(buf, "%d", (uint32_t)-1));
271 EXPECT_EQ("4294967295", std::string(buf));
272 EXPECT_EQ(1, Format(buf, "%d", (int32_t)1));
273 EXPECT_EQ("1", std::string(buf));
274 EXPECT_EQ(2, Format(buf, "%d", (int32_t)-1));
275 EXPECT_EQ("-1", std::string(buf));
276 // Work-around for an limitation of C90
277 EXPECT_EQ(11, Format(buf, "%d", (int32_t)-2147483647-1));
278 EXPECT_EQ("-2147483648", std::string(buf));
279
280 // Quads
281 EXPECT_EQ(1, Format(buf, "%d", (uint64_t)1));
282 EXPECT_EQ("1", std::string(buf));
283 EXPECT_EQ(20, Format(buf, "%d", (uint64_t)-1));
284 EXPECT_EQ("18446744073709551615", std::string(buf));
285 EXPECT_EQ(1, Format(buf, "%d", (int64_t)1));
286 EXPECT_EQ("1", std::string(buf));
287 EXPECT_EQ(2, Format(buf, "%d", (int64_t)-1));
288 EXPECT_EQ("-1", std::string(buf));
289 // Work-around for an limitation of C90
290 EXPECT_EQ(20, Format(buf, "%d", (int64_t)-9223372036854775807LL-1));
291 EXPECT_EQ("-9223372036854775808", std::string(buf));
292
293 // Strings (both const and mutable).
294 EXPECT_EQ(4, Format(buf, "test"));
295 EXPECT_EQ("test", std::string(buf));
296 EXPECT_EQ(4, Format(buf, buf));
297 EXPECT_EQ("test", std::string(buf));
298
299 // Pointer
300 char addr[20];
301 sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf);
302 Format(buf, "%p", buf);
303 EXPECT_EQ(std::string(addr), std::string(buf));
304 Format(buf, "%p", (const char *)buf);
305 EXPECT_EQ(std::string(addr), std::string(buf));
306 sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)sprintf);
307 Format(buf, "%p", sprintf);
308 EXPECT_EQ(std::string(addr), std::string(buf));
309
310 // Padding for pointers is a little more complicated because of the "0x"
311 // prefix. Padding with '0' zeros is relatively straight-forward, but
312 // padding with ' ' spaces requires more effort.
313 sprintf(addr, "0x%017llX", (unsigned long long)(uintptr_t)buf);
314 Format(buf, "%019p", buf);
315 EXPECT_EQ(std::string(addr), std::string(buf));
316 sprintf(addr, "0x%llX", (unsigned long long)(uintptr_t)buf);
317 memset(addr, ' ',
318 (char *)memmove(addr + sizeof(addr) - strlen(addr) - 1,
319 addr, strlen(addr)+1) - addr);
320 Format(buf, "%19p", buf);
321 EXPECT_EQ(std::string(addr), std::string(buf));
322 }
323
324 namespace {
325 void PrintLongString(char* buf, size_t sz) {
326 // Output a reasonably complex expression into a limited-size buffer.
327 // At least one byte is available for writing the NUL character.
328 CHECK_GT(sz, static_cast<size_t>(0));
329
330 // Allocate slightly more space, so that we can verify that Format()
331 // never writes past the end of the buffer.
332 char *tmp = new char[sz+2];
333 memset(tmp, 'X', sz+2);
334
335 // Use Format() to output a complex list of arguments:
336 // - test padding and truncating %c single characters.
337 // - test truncating %s simple strings.
338 // - test mismatching arguments and truncating (for %d != %s).
339 // - test zero-padding and truncating %x hexadecimal numbers.
340 // - test outputting and truncating %d MININT.
341 // - test outputting and truncating %p arbitrary pointer values.
342 // - test outputting, padding and truncating NULL-pointer %s strings.
343 size_t needed = FormatN(tmp, sz,
344 #ifdef NDEBUG
345 "A%2cong %s: %d %010X %d %p%7s", 'l', "string", "",
346 #else
347 "A%2cong %s: %%d %010X %d %p%7s", 'l', "string",
348 #endif
349 0xDEADBEEF, std::numeric_limits<intptr_t>::min(),
350 PrintLongString, static_cast<char*>(NULL)) + 1;
351
352 // Various sanity checks:
353 // The numbered of characters needed to print the full string should always
354 // be bigger or equal to the bytes that have actually been output.
355 size_t len = strlen(tmp);
356 CHECK_GE(needed, len+1);
357
358 // The number of characters output should always fit into the buffer that
359 // was passed into Format().
360 CHECK_LT(len, sz);
361
362 // The output is always terminated with a NUL byte (actually, this test is
363 // always going to pass, as strlen() already verified this)
364 EXPECT_FALSE(tmp[len]);
365
366 // All trailing bytes are unchanged.
367 for (size_t i = len+1; i < sz+2; ++i)
368 EXPECT_EQ('X', tmp[i]);
369
370 // The text that was generated by Format() should always match the
371 // equivalent text generated by sprintf(). Please note that the format
372 // string for sprintf() is nor complicated, as it does not have the
373 // benefit of getting type information from the C++ compiler.
374 //
375 // N.B.: It would be so much cleaner to use snprintf(). But unfortunately,
376 // Visual Studio doesn't support this function, and the work-arounds
377 // are all really awkward.
378 char ref[256];
379 CHECK_LE(sz, sizeof(ref));
380 sprintf(ref, "A long string: %%d 00DEADBEEF %lld 0x%llX <NULL>",
381 static_cast<long long>(std::numeric_limits<intptr_t>::min()),
382 (long long)PrintLongString);
383 ref[sz-1] = '\000';
384
385 // Compare the output from Format() to the one from sprintf().
386 EXPECT_EQ(std::string(ref), std::string(tmp));
387
388 // We allocated a slightly larger buffer, so that we could perform some
389 // extra sanity checks. Now that the tests have all passed, we copy the
390 // data to the output buffer that the caller provided.
391 memcpy(buf, tmp, len+1);
392 delete[] tmp;
393 }
394 } // anonymous namespace
395
396 TEST(FormatTest, Truncation) {
397 // We use PrintLongString() to print a complex long string and then
398 // truncate to all possible lengths. This ends up exercising a lot of
399 // different code paths in Format() and itoa_r(), as truncation can
400 // happen in a lot of different states.
401 char ref[256];
402 PrintLongString(ref, sizeof(ref));
403 for (size_t i = strlen(ref)+1; i; --i) {
404 char buf[sizeof(ref)];
405 PrintLongString(buf, i);
406 EXPECT_EQ(std::string(ref, i - 1), std::string(buf));
407 }
408 }
409
410 TEST(FormatTest, Padding) {
411 char buf[40], fmt[40];
412
413 // Chars %c
414 EXPECT_EQ(1, Format(buf, "%c", 'A'));
415 EXPECT_EQ("A", std::string(buf));
416 EXPECT_EQ(2, Format(buf, "%2c", 'A'));
417 EXPECT_EQ(" A", std::string(buf));
418 EXPECT_EQ(2, Format(buf, "%02c", 'A'));
419 EXPECT_EQ(" A", std::string(buf));
420 EXPECT_EQ(4, Format(buf, "%-2c", 'A'));
421 EXPECT_EQ("%-2c", std::string(buf));
422 Format(fmt, "%%%dc", std::numeric_limits<ssize_t>::max());
423 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, Format(buf, fmt, 'A'));
424 #ifdef NDEBUG
425 Format(fmt, "%%%dc",
426 static_cast<size_t>(std::numeric_limits<ssize_t>::max())+1);
427 EXPECT_EQ(2, Format(buf, fmt, 'A'));
428 EXPECT_EQ("%c", std::string(buf));
429 #endif
430
431 // Decimals %d
432 EXPECT_EQ(1, Format(buf, "%d", 1));
433 EXPECT_EQ("1", std::string(buf));
434 EXPECT_EQ(2, Format(buf, "%2d", 1));
435 EXPECT_EQ(" 1", std::string(buf));
436 EXPECT_EQ(2, Format(buf, "%02d", 1));
437 EXPECT_EQ("01", std::string(buf));
438 EXPECT_EQ(3, Format(buf, "%3d", -1));
439 EXPECT_EQ(" -1", std::string(buf));
440 EXPECT_EQ(3, Format(buf, "%03d", -1));
441 EXPECT_EQ("-01", std::string(buf));
442 EXPECT_EQ(3, Format(buf, "%2d", 111));
443 EXPECT_EQ("111", std::string(buf));
444 EXPECT_EQ(4, Format(buf, "%2d", -111));
445 EXPECT_EQ("-111", std::string(buf));
446 EXPECT_EQ(4, Format(buf, "%-2d", 1));
447 EXPECT_EQ("%-2d", std::string(buf));
448 Format(fmt, "%%%dd", std::numeric_limits<ssize_t>::max());
449 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, FormatN(buf, 4, fmt, 1));
450 EXPECT_EQ(" ", std::string(buf));
451 Format(fmt, "%%0%dd", std::numeric_limits<ssize_t>::max());
452 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, FormatN(buf, 4, fmt, 1));
453 EXPECT_EQ("000", std::string(buf));
454 #ifdef NDEBUG
455 Format(fmt, "%%%dd",
456 static_cast<size_t>(std::numeric_limits<ssize_t>::max())+1);
457 EXPECT_EQ(2, Format(buf, fmt, 1));
458 EXPECT_EQ("%d", std::string(buf));
459 #endif
460
461 // Hex %X
462 EXPECT_EQ(1, Format(buf, "%X", 1));
463 EXPECT_EQ("1", std::string(buf));
464 EXPECT_EQ(2, Format(buf, "%2X", 1));
465 EXPECT_EQ(" 1", std::string(buf));
466 EXPECT_EQ(2, Format(buf, "%02X", 1));
467 EXPECT_EQ("01", std::string(buf));
468 EXPECT_EQ(8, Format(buf, "%3X", -1));
469 EXPECT_EQ("FFFFFFFF", std::string(buf));
470 EXPECT_EQ(8, Format(buf, "%03X", -1));
471 EXPECT_EQ("FFFFFFFF", std::string(buf));
472 EXPECT_EQ(16, Format(buf, "%3X", -1LL));
473 EXPECT_EQ("FFFFFFFFFFFFFFFF", std::string(buf));
474 EXPECT_EQ(16, Format(buf, "%03X", -1LL));
475 EXPECT_EQ("FFFFFFFFFFFFFFFF", std::string(buf));
476 EXPECT_EQ(3, Format(buf, "%2X", 0x111));
477 EXPECT_EQ("111", std::string(buf));
478 EXPECT_EQ(4, Format(buf, "%-2X", 1));
479 EXPECT_EQ("%-2X", std::string(buf));
480 Format(fmt, "%%%dX", std::numeric_limits<ssize_t>::max());
481 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, FormatN(buf, 4, fmt, 1));
482 EXPECT_EQ(" ", std::string(buf));
483 Format(fmt, "%%0%dX", std::numeric_limits<ssize_t>::max());
484 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, FormatN(buf, 4, fmt, 1));
485 EXPECT_EQ("000", std::string(buf));
486 #ifdef NDEBUG
487 Format(fmt, "%%%dX",
488 static_cast<size_t>(std::numeric_limits<ssize_t>::max())+1);
489 EXPECT_EQ(2, Format(buf, fmt, 1));
490 EXPECT_EQ("%X", std::string(buf));
491 #endif
492
493 // Pointer %p
494 EXPECT_EQ(3, Format(buf, "%p", (void*)1));
495 EXPECT_EQ("0x1", std::string(buf));
496 EXPECT_EQ(4, Format(buf, "%4p", (void*)1));
497 EXPECT_EQ(" 0x1", std::string(buf));
498 EXPECT_EQ(4, Format(buf, "%04p", (void*)1));
499 EXPECT_EQ("0x01", std::string(buf));
500 EXPECT_EQ(5, Format(buf, "%4p", (void*)0x111));
501 EXPECT_EQ("0x111", std::string(buf));
502 EXPECT_EQ(4, Format(buf, "%-2p", (void*)1));
503 EXPECT_EQ("%-2p", std::string(buf));
504 Format(fmt, "%%%dp", std::numeric_limits<ssize_t>::max());
505 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
506 FormatN(buf, 4, fmt, (void*)1));
507 EXPECT_EQ(" ", std::string(buf));
508 Format(fmt, "%%0%dp", std::numeric_limits<ssize_t>::max());
509 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1,
510 FormatN(buf, 4, fmt, (void*)1));
511 EXPECT_EQ("0x0", std::string(buf));
512 #ifdef NDEBUG
513 Format(fmt, "%%%dp",
514 static_cast<size_t>(std::numeric_limits<ssize_t>::max())+1);
515 EXPECT_EQ(2, Format(buf, fmt, 1));
516 EXPECT_EQ("%p", std::string(buf));
517 #endif
518
519 // String
520 EXPECT_EQ(1, Format(buf, "%s", "A"));
521 EXPECT_EQ("A", std::string(buf));
522 EXPECT_EQ(2, Format(buf, "%2s", "A"));
523 EXPECT_EQ(" A", std::string(buf));
524 EXPECT_EQ(2, Format(buf, "%02s", "A"));
525 EXPECT_EQ(" A", std::string(buf));
526 EXPECT_EQ(3, Format(buf, "%2s", "AAA"));
527 EXPECT_EQ("AAA", std::string(buf));
528 EXPECT_EQ(4, Format(buf, "%-2s", "A"));
529 EXPECT_EQ("%-2s", std::string(buf));
530 Format(fmt, "%%%ds", std::numeric_limits<ssize_t>::max());
531 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, FormatN(buf, 4, fmt, "A"));
532 EXPECT_EQ(" ", std::string(buf));
533 Format(fmt, "%%0%ds", std::numeric_limits<ssize_t>::max());
534 EXPECT_EQ(std::numeric_limits<ssize_t>::max()-1, FormatN(buf, 4, fmt, "A"));
535 EXPECT_EQ(" ", std::string(buf));
536 #ifdef NDEBUG
537 Format(fmt, "%%%ds",
538 static_cast<size_t>(std::numeric_limits<ssize_t>::max())+1);
539 EXPECT_EQ(2, Format(buf, fmt, "A"));
540 EXPECT_EQ("%s", std::string(buf));
541 #endif
542 }
543
544 TEST(FormatTest, EmbeddedNul) {
545 char buf[] = { 'X', 'X', 'X', 'X' };
546 EXPECT_EQ(2, Format(buf, "%3c", 0));
547 EXPECT_EQ(' ', buf[0]);
548 EXPECT_EQ(' ', buf[1]);
549 EXPECT_EQ(0, buf[2]);
550 EXPECT_EQ('X', buf[3]);
551
552 // Check handling of a NUL format character. N.B. this takes two different
553 // code paths depending on whether we are actually passing arguments. If
554 // we don't have any arguments, we are running in the fast-path code, that
555 // looks (almost) like a strncpy().
556 EXPECT_EQ(2, Format(buf, "%%%"));
557 EXPECT_EQ("%%", std::string(buf));
558 EXPECT_EQ(2, Format(buf, "%%%", 0));
559 EXPECT_EQ("%%", std::string(buf));
560 }
561
562 TEST(FormatTest, EmitNULL) {
563 char buf[40];
564 #ifdef __GNUC__
565 #pragma GCC diagnostic push
566 #pragma GCC diagnostic ignored "-Wconversion-null"
567 #endif
568 EXPECT_EQ(1, Format(buf, "%d", NULL));
569 EXPECT_EQ("0", std::string(buf));
570 EXPECT_EQ(3, Format(buf, "%p", NULL));
571 EXPECT_EQ("0x0", std::string(buf));
572 EXPECT_EQ(6, Format(buf, "%s", NULL));
573 EXPECT_EQ("<NULL>", std::string(buf));
574 #ifdef __GCC__
575 #pragma GCC diagnostic pop
576 #endif
577 }
578
579 TEST(FormatTest, PointerSize) {
580 // The internal data representation is a 64bit value, independent of the
581 // native word size. We want to perform sign-extension for signed integers,
582 // but we want to avoid doing so for pointer types. This could be a
583 // problem on systems, where pointers are only 32bit. This tests verifies
584 // that there is no such problem.
585 char *str = reinterpret_cast<char *>(0x80000000u);
586 void *ptr = str;
587 char buf[40];
588 EXPECT_EQ(10, Format(buf, "%p", str));
589 EXPECT_EQ("0x80000000", std::string(buf));
590 EXPECT_EQ(10, Format(buf, "%p", ptr));
591 EXPECT_EQ("0x80000000", std::string(buf));
592 }
593
594 } // namespace debug
595 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698