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/stringprintf.h"
6*6777b538SAndroid Build Coastguard Worker
7*6777b538SAndroid Build Coastguard Worker #include <errno.h>
8*6777b538SAndroid Build Coastguard Worker #include <stddef.h>
9*6777b538SAndroid Build Coastguard Worker
10*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
11*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
12*6777b538SAndroid Build Coastguard Worker
13*6777b538SAndroid Build Coastguard Worker namespace base {
14*6777b538SAndroid Build Coastguard Worker
15*6777b538SAndroid Build Coastguard Worker namespace {
16*6777b538SAndroid Build Coastguard Worker
17*6777b538SAndroid Build Coastguard Worker // A helper for the StringAppendV test that follows.
18*6777b538SAndroid Build Coastguard Worker //
19*6777b538SAndroid Build Coastguard Worker // Just forwards its args to StringAppendV.
20*6777b538SAndroid Build Coastguard Worker template <class CharT>
StringAppendVTestHelper(std::basic_string<CharT> * out,const CharT * format,...)21*6777b538SAndroid Build Coastguard Worker static void StringAppendVTestHelper(std::basic_string<CharT>* out,
22*6777b538SAndroid Build Coastguard Worker const CharT* format,
23*6777b538SAndroid Build Coastguard Worker ...) {
24*6777b538SAndroid Build Coastguard Worker va_list ap;
25*6777b538SAndroid Build Coastguard Worker va_start(ap, format);
26*6777b538SAndroid Build Coastguard Worker StringAppendV(out, format, ap);
27*6777b538SAndroid Build Coastguard Worker va_end(ap);
28*6777b538SAndroid Build Coastguard Worker }
29*6777b538SAndroid Build Coastguard Worker
30*6777b538SAndroid Build Coastguard Worker } // namespace
31*6777b538SAndroid Build Coastguard Worker
TEST(StringPrintfTest,StringPrintfEmpty)32*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfEmpty) {
33*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", StringPrintf("%s", ""));
34*6777b538SAndroid Build Coastguard Worker }
35*6777b538SAndroid Build Coastguard Worker
TEST(StringPrintfTest,StringPrintfMisc)36*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfMisc) {
37*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w'));
38*6777b538SAndroid Build Coastguard Worker }
39*6777b538SAndroid Build Coastguard Worker
TEST(StringPrintfTest,StringAppendfEmptyString)40*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendfEmptyString) {
41*6777b538SAndroid Build Coastguard Worker std::string value("Hello");
42*6777b538SAndroid Build Coastguard Worker StringAppendF(&value, "%s", "");
43*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Hello", value);
44*6777b538SAndroid Build Coastguard Worker }
45*6777b538SAndroid Build Coastguard Worker
TEST(StringPrintfTest,StringAppendfString)46*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendfString) {
47*6777b538SAndroid Build Coastguard Worker std::string value("Hello");
48*6777b538SAndroid Build Coastguard Worker StringAppendF(&value, " %s", "World");
49*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Hello World", value);
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker
TEST(StringPrintfTest,StringAppendfInt)52*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendfInt) {
53*6777b538SAndroid Build Coastguard Worker std::string value("Hello");
54*6777b538SAndroid Build Coastguard Worker StringAppendF(&value, " %d", 123);
55*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("Hello 123", value);
56*6777b538SAndroid Build Coastguard Worker }
57*6777b538SAndroid Build Coastguard Worker
58*6777b538SAndroid Build Coastguard Worker // Make sure that lengths exactly around the initial buffer size are handled
59*6777b538SAndroid Build Coastguard Worker // correctly.
TEST(StringPrintfTest,StringPrintfBounds)60*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfBounds) {
61*6777b538SAndroid Build Coastguard Worker const int kSrcLen = 1026;
62*6777b538SAndroid Build Coastguard Worker char src[kSrcLen];
63*6777b538SAndroid Build Coastguard Worker std::fill_n(src, kSrcLen, 'A');
64*6777b538SAndroid Build Coastguard Worker
65*6777b538SAndroid Build Coastguard Worker wchar_t srcw[kSrcLen];
66*6777b538SAndroid Build Coastguard Worker std::fill_n(srcw, kSrcLen, 'A');
67*6777b538SAndroid Build Coastguard Worker
68*6777b538SAndroid Build Coastguard Worker char16_t src16[kSrcLen];
69*6777b538SAndroid Build Coastguard Worker std::fill_n(src16, kSrcLen, 'A');
70*6777b538SAndroid Build Coastguard Worker
71*6777b538SAndroid Build Coastguard Worker for (int i = 1; i < 3; i++) {
72*6777b538SAndroid Build Coastguard Worker src[kSrcLen - i] = 0;
73*6777b538SAndroid Build Coastguard Worker std::string out;
74*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(src, StringPrintf("%s", src));
75*6777b538SAndroid Build Coastguard Worker }
76*6777b538SAndroid Build Coastguard Worker }
77*6777b538SAndroid Build Coastguard Worker
78*6777b538SAndroid Build Coastguard Worker // Test very large sprintfs that will cause the buffer to grow.
TEST(StringPrintfTest,Grow)79*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, Grow) {
80*6777b538SAndroid Build Coastguard Worker char src[1026];
81*6777b538SAndroid Build Coastguard Worker for (auto& i : src)
82*6777b538SAndroid Build Coastguard Worker i = 'A';
83*6777b538SAndroid Build Coastguard Worker src[1025] = 0;
84*6777b538SAndroid Build Coastguard Worker
85*6777b538SAndroid Build Coastguard Worker const char fmt[] = "%sB%sB%sB%sB%sB%sB%s";
86*6777b538SAndroid Build Coastguard Worker
87*6777b538SAndroid Build Coastguard Worker const int kRefSize = 320000;
88*6777b538SAndroid Build Coastguard Worker char* ref = new char[kRefSize];
89*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
90*6777b538SAndroid Build Coastguard Worker sprintf_s(ref, kRefSize, fmt, src, src, src, src, src, src, src);
91*6777b538SAndroid Build Coastguard Worker #elif BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_FUCHSIA)
92*6777b538SAndroid Build Coastguard Worker snprintf(ref, kRefSize, fmt, src, src, src, src, src, src, src);
93*6777b538SAndroid Build Coastguard Worker #endif
94*6777b538SAndroid Build Coastguard Worker
95*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(ref, StringPrintf(fmt, src, src, src, src, src, src, src));
96*6777b538SAndroid Build Coastguard Worker delete[] ref;
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker
TEST(StringPrintfTest,StringAppendV)99*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringAppendV) {
100*6777b538SAndroid Build Coastguard Worker std::string out;
101*6777b538SAndroid Build Coastguard Worker StringAppendVTestHelper(&out, "%d foo %s", 1, "bar");
102*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("1 foo bar", out);
103*6777b538SAndroid Build Coastguard Worker }
104*6777b538SAndroid Build Coastguard Worker
105*6777b538SAndroid Build Coastguard Worker // Test the boundary condition for the size of the string_util's
106*6777b538SAndroid Build Coastguard Worker // internal buffer.
TEST(StringPrintfTest,GrowBoundary)107*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, GrowBoundary) {
108*6777b538SAndroid Build Coastguard Worker const int kStringUtilBufLen = 1024;
109*6777b538SAndroid Build Coastguard Worker // Our buffer should be one larger than the size of StringAppendVT's stack
110*6777b538SAndroid Build Coastguard Worker // buffer.
111*6777b538SAndroid Build Coastguard Worker // And need extra one for NULL-terminator.
112*6777b538SAndroid Build Coastguard Worker const int kBufLen = kStringUtilBufLen + 1 + 1;
113*6777b538SAndroid Build Coastguard Worker char src[kBufLen];
114*6777b538SAndroid Build Coastguard Worker for (int i = 0; i < kBufLen - 1; ++i)
115*6777b538SAndroid Build Coastguard Worker src[i] = 'a';
116*6777b538SAndroid Build Coastguard Worker src[kBufLen - 1] = 0;
117*6777b538SAndroid Build Coastguard Worker
118*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(src, StringPrintf("%s", src));
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker
121*6777b538SAndroid Build Coastguard Worker // Test that StringPrintf and StringAppendV do not change errno.
TEST(StringPrintfTest,StringPrintfErrno)122*6777b538SAndroid Build Coastguard Worker TEST(StringPrintfTest, StringPrintfErrno) {
123*6777b538SAndroid Build Coastguard Worker errno = 1;
124*6777b538SAndroid Build Coastguard Worker EXPECT_EQ("", StringPrintf("%s", ""));
125*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, errno);
126*6777b538SAndroid Build Coastguard Worker std::string out;
127*6777b538SAndroid Build Coastguard Worker StringAppendVTestHelper(&out, "%d foo %s", 1, "bar");
128*6777b538SAndroid Build Coastguard Worker EXPECT_EQ(1, errno);
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker
131*6777b538SAndroid Build Coastguard Worker } // namespace base
132