protobuf/src/google/protobuf/stubs/stringprintf_unittest.cc
Go to the documentation of this file.
1 // Protocol Buffers - Google's data interchange format
2 // Copyright 2012 Google Inc. All rights reserved.
3 // https://developers.google.com/protocol-buffers/
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are
7 // met:
8 //
9 // * Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
11 // * Redistributions in binary form must reproduce the above
12 // copyright notice, this list of conditions and the following disclaimer
13 // in the documentation and/or other materials provided with the
14 // distribution.
15 // * Neither the name of Google Inc. nor the names of its
16 // contributors may be used to endorse or promote products derived from
17 // this software without specific prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 
31 // from google3/base/stringprintf_unittest.cc
32 
33 #include <google/protobuf/stubs/stringprintf.h>
34 #include <google/protobuf/testing/googletest.h>
35 #include <gtest/gtest.h>
36 
37 #include <array>
38 #include <cerrno>
39 #include <string>
40 
41 namespace google {
42 namespace protobuf {
43 namespace {
44 
45 TEST(StringPrintfTest, Empty) {
46 #if 0
47  // gcc 2.95.3, gcc 4.1.0, and gcc 4.2.2 all warn about this:
48  // warning: zero-length printf format string.
49  // so we do not allow them in google3.
50  EXPECT_EQ("", StringPrintf(""));
51 #endif
52  EXPECT_EQ("", StringPrintf("%s", std::string().c_str()));
53  EXPECT_EQ("", StringPrintf("%s", ""));
54 }
55 
56 TEST(StringPrintfTest, Misc) {
57 // MSVC and mingw does not support $ format specifier.
58 #if !defined(_MSC_VER) && !defined(__MINGW32__)
59  EXPECT_EQ("123hello w", StringPrintf("%3$d%2$s %1$c", 'w', "hello", 123));
60 #endif // !_MSC_VER
61 }
62 
63 TEST(StringAppendFTest, Empty) {
64  std::string value("Hello");
65  const char* empty = "";
66  StringAppendF(&value, "%s", empty);
67  EXPECT_EQ("Hello", value);
68 }
69 
70 TEST(StringAppendFTest, EmptyString) {
71  std::string value("Hello");
72  StringAppendF(&value, "%s", "");
73  EXPECT_EQ("Hello", value);
74 }
75 
76 TEST(StringAppendFTest, String) {
77  std::string value("Hello");
78  StringAppendF(&value, " %s", "World");
79  EXPECT_EQ("Hello World", value);
80 }
81 
82 TEST(StringAppendFTest, Int) {
83  std::string value("Hello");
84  StringAppendF(&value, " %d", 123);
85  EXPECT_EQ("Hello 123", value);
86 }
87 
88 TEST(StringPrintfTest, Multibyte) {
89  // If we are in multibyte mode and feed invalid multibyte sequence,
90  // StringPrintf should return an empty string instead of running
91  // out of memory while trying to determine destination buffer size.
92  // see b/4194543.
93 
94  char* old_locale_c = setlocale(LC_CTYPE, nullptr);
95  ASSERT_TRUE(old_locale_c != nullptr);
96  std::string old_locale = old_locale_c;
97  // Push locale with multibyte mode
98  setlocale(LC_CTYPE, "en_US.utf8");
99 
100  const char kInvalidCodePoint[] = "\375\067s";
101  std::string value = StringPrintf("%.*s", 3, kInvalidCodePoint);
102 
103  // In some versions of glibc (e.g. eglibc-2.11.1, aka GRTEv2), snprintf
104  // returns error given an invalid codepoint. Other versions
105  // (e.g. eglibc-2.15, aka pre-GRTEv3) emit the codepoint verbatim.
106  // We test that the output is one of the above.
107  EXPECT_TRUE(value.empty() || value == kInvalidCodePoint);
108 
109  // Repeat with longer string, to make sure that the dynamically
110  // allocated path in StringAppendV is handled correctly.
111  const size_t n = 2048;
112  std::array<char, n + 1> buf;
113  memset(&buf[0], ' ', n - 3);
114  memcpy(&buf[0] + n - 3, kInvalidCodePoint, 4);
115  value = StringPrintf("%.*s", n, &buf[0]);
116  // See GRTEv2 vs. GRTEv3 comment above.
117  EXPECT_TRUE(value.empty() || value == &buf[0]);
118 
119  setlocale(LC_CTYPE, old_locale.c_str());
120 }
121 
122 TEST(StringPrintfTest, NoMultibyte) {
123  // No multibyte handling, but the string contains funny chars.
124  char* old_locale_c = setlocale(LC_CTYPE, nullptr);
125  ASSERT_TRUE(old_locale_c != nullptr);
126  std::string old_locale = old_locale_c;
127  setlocale(LC_CTYPE, "POSIX");
128  std::string value = StringPrintf("%.*s", 3, "\375\067s");
129  setlocale(LC_CTYPE, old_locale.c_str());
130  EXPECT_EQ("\375\067s", value);
131 }
132 
133 TEST(StringPrintfTest, DontOverwriteErrno) {
134  // Check that errno isn't overwritten unless we're printing
135  // something significantly larger than what people are normally
136  // printing in their badly written PLOG() statements.
137  errno = ECHILD;
138  std::string value = StringPrintf("Hello, %s!", "World");
139  EXPECT_EQ(ECHILD, errno);
140 }
141 
142 TEST(StringPrintfTest, LargeBuf) {
143  // Check that the large buffer is handled correctly.
144  int n = 2048;
145  char* buf = new char[n+1];
146  memset(buf, ' ', n);
147  buf[n] = 0;
149  EXPECT_EQ(buf, value);
150  delete[] buf;
151 }
152 
153 } // anonymous namespace
154 } // namespace protobuf
155 } // namespace google
google::protobuf::value
const Descriptor::ReservedRange value
Definition: bloaty/third_party/protobuf/src/google/protobuf/descriptor.h:1954
memset
return memset(p, 0, total)
buf
voidpf void * buf
Definition: bloaty/third_party/zlib/contrib/minizip/ioapi.h:136
testing::internal::string
::std::string string
Definition: bloaty/third_party/protobuf/third_party/googletest/googletest/include/gtest/internal/gtest-port.h:881
google::protobuf
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:12
google::protobuf::StringAppendF
void StringAppendF(string *dst, const char *format,...)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc:127
EXPECT_EQ
#define EXPECT_EQ(a, b)
Definition: iomgr/time_averaged_stats_test.cc:27
memcpy
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
gen_stats_data.c_str
def c_str(s, encoding='ascii')
Definition: gen_stats_data.py:38
google::protobuf::StringPrintf
string StringPrintf(const char *format,...)
Definition: bloaty/third_party/protobuf/src/google/protobuf/stubs/stringprintf.cc:109
google::protobuf::TEST
TEST(ArenaTest, ArenaConstructable)
Definition: bloaty/third_party/protobuf/src/google/protobuf/arena_unittest.cc:156
Json::Int
int Int
Definition: third_party/bloaty/third_party/protobuf/conformance/third_party/jsoncpp/json.h:228
n
int n
Definition: abseil-cpp/absl/container/btree_test.cc:1080
Empty
Definition: abseil-cpp/absl/container/internal/compressed_tuple_test.cc:33
google_benchmark.example.empty
def empty(state)
Definition: example.py:31
ASSERT_TRUE
#define ASSERT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1973
EXPECT_TRUE
#define EXPECT_TRUE(condition)
Definition: bloaty/third_party/googletest/googletest/include/gtest/gtest.h:1967
google
Definition: bloaty/third_party/protobuf/benchmarks/util/data_proto2_to_proto3_util.h:11


grpc
Author(s):
autogenerated on Fri May 16 2025 03:00:22