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