xref: /aosp_15_r20/external/libchrome/base/strings/stringprintf_unittest.cc (revision 635a864187cb8b6c713ff48b7e790a6b21769273)
1*635a8641SAndroid Build Coastguard Worker // Copyright 2013 The Chromium Authors. All rights reserved.
2*635a8641SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*635a8641SAndroid Build Coastguard Worker // found in the LICENSE file.
4*635a8641SAndroid Build Coastguard Worker 
5*635a8641SAndroid Build Coastguard Worker #include "base/strings/stringprintf.h"
6*635a8641SAndroid Build Coastguard Worker 
7*635a8641SAndroid Build Coastguard Worker #include <errno.h>
8*635a8641SAndroid Build Coastguard Worker #include <stddef.h>
9*635a8641SAndroid Build Coastguard Worker 
10*635a8641SAndroid Build Coastguard Worker #include "base/macros.h"
11*635a8641SAndroid Build Coastguard Worker #include "build/build_config.h"
12*635a8641SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
13*635a8641SAndroid Build Coastguard Worker 
14*635a8641SAndroid Build Coastguard Worker namespace base {
15*635a8641SAndroid Build Coastguard Worker 
16*635a8641SAndroid Build Coastguard Worker namespace {
17*635a8641SAndroid Build Coastguard Worker 
18*635a8641SAndroid Build Coastguard Worker // A helper for the StringAppendV test that follows.
19*635a8641SAndroid Build Coastguard Worker //
20*635a8641SAndroid Build Coastguard Worker // Just forwards its args to StringAppendV.
StringAppendVTestHelper(std::string * out,const char * format,...)21*635a8641SAndroid Build Coastguard Worker static void StringAppendVTestHelper(std::string* out, const char* format, ...) {
22*635a8641SAndroid Build Coastguard Worker   va_list ap;
23*635a8641SAndroid Build Coastguard Worker   va_start(ap, format);
24*635a8641SAndroid Build Coastguard Worker   StringAppendV(out, format, ap);
25*635a8641SAndroid Build Coastguard Worker   va_end(ap);
26*635a8641SAndroid Build Coastguard Worker }
27*635a8641SAndroid Build Coastguard Worker 
28*635a8641SAndroid Build Coastguard Worker }  // namespace
29*635a8641SAndroid Build Coastguard Worker 
TEST(StringPrintfTest,StringPrintfEmpty)30*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfEmpty) {
31*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("", StringPrintf("%s", ""));
32*635a8641SAndroid Build Coastguard Worker }
33*635a8641SAndroid Build Coastguard Worker 
TEST(StringPrintfTest,StringPrintfMisc)34*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfMisc) {
35*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w'));
36*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
37*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2ls %1lc", 123, L"hello", 'w'));
38*635a8641SAndroid Build Coastguard Worker #endif
39*635a8641SAndroid Build Coastguard Worker }
40*635a8641SAndroid Build Coastguard Worker 
TEST(StringPrintfTest,StringAppendfEmptyString)41*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendfEmptyString) {
42*635a8641SAndroid Build Coastguard Worker   std::string value("Hello");
43*635a8641SAndroid Build Coastguard Worker   StringAppendF(&value, "%s", "");
44*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("Hello", value);
45*635a8641SAndroid Build Coastguard Worker 
46*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
47*635a8641SAndroid Build Coastguard Worker   std::wstring valuew(L"Hello");
48*635a8641SAndroid Build Coastguard Worker   StringAppendF(&valuew, L"%ls", L"");
49*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(L"Hello", valuew);
50*635a8641SAndroid Build Coastguard Worker #endif
51*635a8641SAndroid Build Coastguard Worker }
52*635a8641SAndroid Build Coastguard Worker 
TEST(StringPrintfTest,StringAppendfString)53*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendfString) {
54*635a8641SAndroid Build Coastguard Worker   std::string value("Hello");
55*635a8641SAndroid Build Coastguard Worker   StringAppendF(&value, " %s", "World");
56*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("Hello World", value);
57*635a8641SAndroid Build Coastguard Worker 
58*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
59*635a8641SAndroid Build Coastguard Worker   std::wstring valuew(L"Hello");
60*635a8641SAndroid Build Coastguard Worker   StringAppendF(&valuew, L" %ls", L"World");
61*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(L"Hello World", valuew);
62*635a8641SAndroid Build Coastguard Worker #endif
63*635a8641SAndroid Build Coastguard Worker }
64*635a8641SAndroid Build Coastguard Worker 
TEST(StringPrintfTest,StringAppendfInt)65*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendfInt) {
66*635a8641SAndroid Build Coastguard Worker   std::string value("Hello");
67*635a8641SAndroid Build Coastguard Worker   StringAppendF(&value, " %d", 123);
68*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("Hello 123", value);
69*635a8641SAndroid Build Coastguard Worker 
70*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
71*635a8641SAndroid Build Coastguard Worker   std::wstring valuew(L"Hello");
72*635a8641SAndroid Build Coastguard Worker   StringAppendF(&valuew, L" %d", 123);
73*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(L"Hello 123", valuew);
74*635a8641SAndroid Build Coastguard Worker #endif
75*635a8641SAndroid Build Coastguard Worker }
76*635a8641SAndroid Build Coastguard Worker 
77*635a8641SAndroid Build Coastguard Worker // Make sure that lengths exactly around the initial buffer size are handled
78*635a8641SAndroid Build Coastguard Worker // correctly.
TEST(StringPrintfTest,StringPrintfBounds)79*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfBounds) {
80*635a8641SAndroid Build Coastguard Worker   const int kSrcLen = 1026;
81*635a8641SAndroid Build Coastguard Worker   char src[kSrcLen];
82*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < arraysize(src); i++)
83*635a8641SAndroid Build Coastguard Worker     src[i] = 'A';
84*635a8641SAndroid Build Coastguard Worker 
85*635a8641SAndroid Build Coastguard Worker   wchar_t srcw[kSrcLen];
86*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < arraysize(srcw); i++)
87*635a8641SAndroid Build Coastguard Worker     srcw[i] = 'A';
88*635a8641SAndroid Build Coastguard Worker 
89*635a8641SAndroid Build Coastguard Worker   for (int i = 1; i < 3; i++) {
90*635a8641SAndroid Build Coastguard Worker     src[kSrcLen - i] = 0;
91*635a8641SAndroid Build Coastguard Worker     std::string out;
92*635a8641SAndroid Build Coastguard Worker     SStringPrintf(&out, "%s", src);
93*635a8641SAndroid Build Coastguard Worker     EXPECT_STREQ(src, out.c_str());
94*635a8641SAndroid Build Coastguard Worker 
95*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
96*635a8641SAndroid Build Coastguard Worker     srcw[kSrcLen - i] = 0;
97*635a8641SAndroid Build Coastguard Worker     std::wstring outw;
98*635a8641SAndroid Build Coastguard Worker     SStringPrintf(&outw, L"%ls", srcw);
99*635a8641SAndroid Build Coastguard Worker     EXPECT_STREQ(srcw, outw.c_str());
100*635a8641SAndroid Build Coastguard Worker #endif
101*635a8641SAndroid Build Coastguard Worker   }
102*635a8641SAndroid Build Coastguard Worker }
103*635a8641SAndroid Build Coastguard Worker 
104*635a8641SAndroid Build Coastguard Worker // Test very large sprintfs that will cause the buffer to grow.
TEST(StringPrintfTest,Grow)105*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, Grow) {
106*635a8641SAndroid Build Coastguard Worker   char src[1026];
107*635a8641SAndroid Build Coastguard Worker   for (size_t i = 0; i < arraysize(src); i++)
108*635a8641SAndroid Build Coastguard Worker     src[i] = 'A';
109*635a8641SAndroid Build Coastguard Worker   src[1025] = 0;
110*635a8641SAndroid Build Coastguard Worker 
111*635a8641SAndroid Build Coastguard Worker   const char fmt[] = "%sB%sB%sB%sB%sB%sB%s";
112*635a8641SAndroid Build Coastguard Worker 
113*635a8641SAndroid Build Coastguard Worker   std::string out;
114*635a8641SAndroid Build Coastguard Worker   SStringPrintf(&out, fmt, src, src, src, src, src, src, src);
115*635a8641SAndroid Build Coastguard Worker 
116*635a8641SAndroid Build Coastguard Worker   const int kRefSize = 320000;
117*635a8641SAndroid Build Coastguard Worker   char* ref = new char[kRefSize];
118*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
119*635a8641SAndroid Build Coastguard Worker   sprintf_s(ref, kRefSize, fmt, src, src, src, src, src, src, src);
120*635a8641SAndroid Build Coastguard Worker #elif defined(OS_POSIX) || defined(OS_FUCHSIA)
121*635a8641SAndroid Build Coastguard Worker   snprintf(ref, kRefSize, fmt, src, src, src, src, src, src, src);
122*635a8641SAndroid Build Coastguard Worker #endif
123*635a8641SAndroid Build Coastguard Worker 
124*635a8641SAndroid Build Coastguard Worker   EXPECT_STREQ(ref, out.c_str());
125*635a8641SAndroid Build Coastguard Worker   delete[] ref;
126*635a8641SAndroid Build Coastguard Worker }
127*635a8641SAndroid Build Coastguard Worker 
TEST(StringPrintfTest,StringAppendV)128*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendV) {
129*635a8641SAndroid Build Coastguard Worker   std::string out;
130*635a8641SAndroid Build Coastguard Worker   StringAppendVTestHelper(&out, "%d foo %s", 1, "bar");
131*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("1 foo bar", out);
132*635a8641SAndroid Build Coastguard Worker }
133*635a8641SAndroid Build Coastguard Worker 
134*635a8641SAndroid Build Coastguard Worker // Test the boundary condition for the size of the string_util's
135*635a8641SAndroid Build Coastguard Worker // internal buffer.
TEST(StringPrintfTest,GrowBoundary)136*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, GrowBoundary) {
137*635a8641SAndroid Build Coastguard Worker   const int kStringUtilBufLen = 1024;
138*635a8641SAndroid Build Coastguard Worker   // Our buffer should be one larger than the size of StringAppendVT's stack
139*635a8641SAndroid Build Coastguard Worker   // buffer.
140*635a8641SAndroid Build Coastguard Worker   // And need extra one for NULL-terminator.
141*635a8641SAndroid Build Coastguard Worker   const int kBufLen = kStringUtilBufLen + 1 + 1;
142*635a8641SAndroid Build Coastguard Worker   char src[kBufLen];
143*635a8641SAndroid Build Coastguard Worker   for (int i = 0; i < kBufLen - 1; ++i)
144*635a8641SAndroid Build Coastguard Worker     src[i] = 'a';
145*635a8641SAndroid Build Coastguard Worker   src[kBufLen - 1] = 0;
146*635a8641SAndroid Build Coastguard Worker 
147*635a8641SAndroid Build Coastguard Worker   std::string out;
148*635a8641SAndroid Build Coastguard Worker   SStringPrintf(&out, "%s", src);
149*635a8641SAndroid Build Coastguard Worker 
150*635a8641SAndroid Build Coastguard Worker   EXPECT_STREQ(src, out.c_str());
151*635a8641SAndroid Build Coastguard Worker }
152*635a8641SAndroid Build Coastguard Worker 
153*635a8641SAndroid Build Coastguard Worker #if defined(OS_WIN)
154*635a8641SAndroid Build Coastguard Worker // vswprintf in Visual Studio 2013 fails when given U+FFFF. This tests that the
155*635a8641SAndroid Build Coastguard Worker // failure case is gracefuly handled. In Visual Studio 2015 the bad character
156*635a8641SAndroid Build Coastguard Worker // is passed through.
TEST(StringPrintfTest,Invalid)157*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, Invalid) {
158*635a8641SAndroid Build Coastguard Worker   wchar_t invalid[2];
159*635a8641SAndroid Build Coastguard Worker   invalid[0] = 0xffff;
160*635a8641SAndroid Build Coastguard Worker   invalid[1] = 0;
161*635a8641SAndroid Build Coastguard Worker 
162*635a8641SAndroid Build Coastguard Worker   std::wstring out;
163*635a8641SAndroid Build Coastguard Worker   SStringPrintf(&out, L"%ls", invalid);
164*635a8641SAndroid Build Coastguard Worker #if _MSC_VER >= 1900
165*635a8641SAndroid Build Coastguard Worker   EXPECT_STREQ(invalid, out.c_str());
166*635a8641SAndroid Build Coastguard Worker #else
167*635a8641SAndroid Build Coastguard Worker   EXPECT_STREQ(L"", out.c_str());
168*635a8641SAndroid Build Coastguard Worker #endif
169*635a8641SAndroid Build Coastguard Worker }
170*635a8641SAndroid Build Coastguard Worker #endif
171*635a8641SAndroid Build Coastguard Worker 
172*635a8641SAndroid Build Coastguard Worker // Test that StringPrintf and StringAppendV do not change errno.
TEST(StringPrintfTest,StringPrintfErrno)173*635a8641SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfErrno) {
174*635a8641SAndroid Build Coastguard Worker   errno = 1;
175*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ("", StringPrintf("%s", ""));
176*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1, errno);
177*635a8641SAndroid Build Coastguard Worker   std::string out;
178*635a8641SAndroid Build Coastguard Worker   StringAppendVTestHelper(&out, "%d foo %s", 1, "bar");
179*635a8641SAndroid Build Coastguard Worker   EXPECT_EQ(1, errno);
180*635a8641SAndroid Build Coastguard Worker }
181*635a8641SAndroid Build Coastguard Worker 
182*635a8641SAndroid Build Coastguard Worker }  // namespace base
183