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