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