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 "base/macros.h" 11 #include "build/build_config.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace base { 15 16 namespace { 17 18 // A helper for the StringAppendV test that follows. 19 // 20 // Just forwards its args to StringAppendV. 21 static void StringAppendVTestHelper(std::string* out, const char* format, ...) { 22 va_list ap; 23 va_start(ap, format); 24 StringAppendV(out, format, ap); 25 va_end(ap); 26 } 27 28 } // namespace 29 30 TEST(StringPrintfTest, StringPrintfEmpty) { 31 EXPECT_EQ("", StringPrintf("%s", "")); 32 } 33 34 TEST(StringPrintfTest, StringPrintfMisc) { 35 EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w')); 36 #if defined(OS_WIN) 37 EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2ls %1lc", 123, L"hello", 'w')); 38 #endif 39 } 40 41 TEST(StringPrintfTest, StringAppendfEmptyString) { 42 std::string value("Hello"); 43 StringAppendF(&value, "%s", ""); 44 EXPECT_EQ("Hello", value); 45 46 #if defined(OS_WIN) 47 std::wstring valuew(L"Hello"); 48 StringAppendF(&valuew, L"%ls", L""); 49 EXPECT_EQ(L"Hello", valuew); 50 #endif 51 } 52 53 TEST(StringPrintfTest, StringAppendfString) { 54 std::string value("Hello"); 55 StringAppendF(&value, " %s", "World"); 56 EXPECT_EQ("Hello World", value); 57 58 #if defined(OS_WIN) 59 std::wstring valuew(L"Hello"); 60 StringAppendF(&valuew, L" %ls", L"World"); 61 EXPECT_EQ(L"Hello World", valuew); 62 #endif 63 } 64 65 TEST(StringPrintfTest, StringAppendfInt) { 66 std::string value("Hello"); 67 StringAppendF(&value, " %d", 123); 68 EXPECT_EQ("Hello 123", value); 69 70 #if defined(OS_WIN) 71 std::wstring valuew(L"Hello"); 72 StringAppendF(&valuew, L" %d", 123); 73 EXPECT_EQ(L"Hello 123", valuew); 74 #endif 75 } 76 77 // Make sure that lengths exactly around the initial buffer size are handled 78 // correctly. 79 TEST(StringPrintfTest, StringPrintfBounds) { 80 const int kSrcLen = 1026; 81 char src[kSrcLen]; 82 for (size_t i = 0; i < arraysize(src); i++) 83 src[i] = 'A'; 84 85 wchar_t srcw[kSrcLen]; 86 for (size_t i = 0; i < arraysize(srcw); i++) 87 srcw[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