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 14namespace base { 15 16namespace { 17 18// A helper for the StringAppendV test that follows. 19// 20// Just forwards its args to StringAppendV. 21static 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 30TEST(StringPrintfTest, StringPrintfEmpty) { 31 EXPECT_EQ("", StringPrintf("%s", "")); 32} 33 34TEST(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 41TEST(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 53TEST(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 65TEST(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. 79TEST(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. 105TEST(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 128TEST(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. 136TEST(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. 157TEST(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. 173TEST(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