diff options
author | mmentovai@google.com <mmentovai@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-13 01:17:18 +0000 |
---|---|---|
committer | mmentovai@google.com <mmentovai@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2008-08-13 01:17:18 +0000 |
commit | 703f427ed4c2e067d95890f8edbbbdc29fc62e1d (patch) | |
tree | 61ec76f580c34d5034a820faf5829b016aa244c3 /base | |
parent | 856ab444ba32f086519a0db875e716844c060560 (diff) | |
download | chromium_src-703f427ed4c2e067d95890f8edbbbdc29fc62e1d.zip chromium_src-703f427ed4c2e067d95890f8edbbbdc29fc62e1d.tar.gz chromium_src-703f427ed4c2e067d95890f8edbbbdc29fc62e1d.tar.bz2 |
Fix string_util and its tests for the Mac, GCC, UTF-32 wchar_t platforms, and POSIX systems generally.
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@771 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base')
-rw-r--r-- | base/base.xcodeproj/project.pbxproj | 12 | ||||
-rw-r--r-- | base/basictypes.h | 9 | ||||
-rw-r--r-- | base/port.h | 25 | ||||
-rw-r--r-- | base/string_util.cc | 91 | ||||
-rw-r--r-- | base/string_util.h | 6 | ||||
-rw-r--r-- | base/string_util_icu.cc | 6 | ||||
-rw-r--r-- | base/string_util_unittest.cc | 147 |
7 files changed, 178 insertions, 118 deletions
diff --git a/base/base.xcodeproj/project.pbxproj b/base/base.xcodeproj/project.pbxproj index d93190d..33fc549 100644 --- a/base/base.xcodeproj/project.pbxproj +++ b/base/base.xcodeproj/project.pbxproj @@ -45,6 +45,8 @@ 7BAF50760E50B8F100CA8A07 /* file_version_info_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF50740E50B8F100CA8A07 /* file_version_info_mac.mm */; }; 7BAF50780E50B8F100CA8A07 /* file_version_info_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF50740E50B8F100CA8A07 /* file_version_info_mac.mm */; }; 7BAF50790E50B8F100CA8A07 /* file_version_info_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF50750E50B8F100CA8A07 /* file_version_info_unittest.cc */; }; + 7BAF50AA0E50BACB00CA8A07 /* string_util_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = 7BAF50A90E50BACB00CA8A07 /* string_util_posix.h */; }; + 7BAF50B20E50BAE700CA8A07 /* string_util_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = 7BAF50B10E50BAE700CA8A07 /* string_util_unittest.cc */; }; 820EB4F00E3A610A009668FC /* linked_ptr.h in Headers */ = {isa = PBXBuildFile; fileRef = 820EB4EF0E3A610A009668FC /* linked_ptr.h */; }; 820EB4F70E3A613F009668FC /* string_piece.cc in Sources */ = {isa = PBXBuildFile; fileRef = 820EB4F50E3A613F009668FC /* string_piece.cc */; }; 820EB4F80E3A613F009668FC /* string_piece.h in Headers */ = {isa = PBXBuildFile; fileRef = 820EB4F60E3A613F009668FC /* string_piece.h */; }; @@ -122,7 +124,6 @@ A5A0284F0E4CFD7E00498DA9 /* file_util_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = A5A0268D0E4A2BDC00498DA9 /* file_util_posix.cc */; }; A5A028520E4CFDE300498DA9 /* path_service_unittest.cc in Sources */ = {isa = PBXBuildFile; fileRef = E4562AD60E27E27E005E4685 /* path_service_unittest.cc */; }; A5A0286B0E4CFFC700498DA9 /* base_paths_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABF4B98E0DC2BA6900A6E319 /* base_paths_mac.mm */; }; - AB5C95780E525A6400F5B56D /* string_util_posix.h in Headers */ = {isa = PBXBuildFile; fileRef = AB5C95760E525A6400F5B56D /* string_util_posix.h */; }; AB5C95790E525A6400F5B56D /* string_util_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB5C95770E525A6400F5B56D /* string_util_posix.cc */; }; ABCFB4E70E525B5C008A8C07 /* string_util_posix.cc in Sources */ = {isa = PBXBuildFile; fileRef = AB5C95770E525A6400F5B56D /* string_util_posix.cc */; }; ABF4B98F0DC2BA6900A6E319 /* base_paths_mac.mm in Sources */ = {isa = PBXBuildFile; fileRef = ABF4B98E0DC2BA6900A6E319 /* base_paths_mac.mm */; }; @@ -363,6 +364,8 @@ 7BAF501B0E50B84200CA8A07 /* base_paths.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = base_paths.cc; sourceTree = "<group>"; }; 7BAF50740E50B8F100CA8A07 /* file_version_info_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = file_version_info_mac.mm; sourceTree = "<group>"; }; 7BAF50750E50B8F100CA8A07 /* file_version_info_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_version_info_unittest.cc; sourceTree = "<group>"; }; + 7BAF50A90E50BACB00CA8A07 /* string_util_posix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_util_posix.h; sourceTree = "<group>"; }; + 7BAF50B10E50BAE700CA8A07 /* string_util_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_util_unittest.cc; sourceTree = "<group>"; }; 7BD9E84E0DA447F800FC7A01 /* singleton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = singleton.h; sourceTree = "<group>"; }; 7BEB81100D9AD288009BA8DD /* prcpucfg_mac.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = prcpucfg_mac.h; path = third_party/nspr/prcpucfg_mac.h; sourceTree = "<group>"; }; 7BEB81490D9B0F33009BA8DD /* time_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = time_posix.cc; sourceTree = "<group>"; }; @@ -519,7 +522,6 @@ A5A0270A0E4A630D00498DA9 /* file_util_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = file_util_mac.mm; sourceTree = "<group>"; }; A5A0276B0E4BA33700498DA9 /* build_config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = build_config.h; path = ../build/build_config.h; sourceTree = SOURCE_ROOT; }; A5A0282D0E4CFA8500498DA9 /* file_util_unittest.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = file_util_unittest.cc; sourceTree = "<group>"; }; - AB5C95760E525A6400F5B56D /* string_util_posix.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = string_util_posix.h; sourceTree = "<group>"; }; AB5C95770E525A6400F5B56D /* string_util_posix.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = string_util_posix.cc; sourceTree = "<group>"; }; ABF4B98E0DC2BA6900A6E319 /* base_paths_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = base_paths_mac.mm; sourceTree = "<group>"; }; ABF4B99D0DC2BB6000A6E319 /* clipboard_mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = clipboard_mac.mm; sourceTree = "<group>"; }; @@ -748,8 +750,9 @@ 8254037C0D92D2CF0006B936 /* string_util.cc */, 8254037D0D92D2CF0006B936 /* string_util.h */, 820EB4F90E3A6178009668FC /* string_util_icu.cc */, - AB5C95760E525A6400F5B56D /* string_util_posix.h */, AB5C95770E525A6400F5B56D /* string_util_posix.cc */, + 7BAF50A90E50BACB00CA8A07 /* string_util_posix.h */, + 7BAF50B10E50BAE700CA8A07 /* string_util_unittest.cc */, 821B91680DAABD7F00F350D7 /* string16.h */, 7B4C5F470E4B6BF900679E8F /* sys_string_conversions.h */, 7B4C5F480E4B6BF900679E8F /* sys_string_conversions_mac.cc */, @@ -945,7 +948,7 @@ A5A0276C0E4BA33700498DA9 /* build_config.h in Headers */, 7BAF4F0B0E50A2FD00CA8A07 /* notimplemented.h in Headers */, 7BAF4F7C0E50A3BD00CA8A07 /* logging.h in Headers */, - AB5C95780E525A6400F5B56D /* string_util_posix.h in Headers */, + 7BAF50AA0E50BACB00CA8A07 /* string_util_posix.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1287,6 +1290,7 @@ 7BAF501D0E50B84200CA8A07 /* base_paths.cc in Sources */, 7BAF50780E50B8F100CA8A07 /* file_version_info_mac.mm in Sources */, 7BAF50790E50B8F100CA8A07 /* file_version_info_unittest.cc in Sources */, + 7BAF50B20E50BAE700CA8A07 /* string_util_unittest.cc in Sources */, E4AFA4A80E50D84900201347 /* prtime.cc in Sources */, E4AFA4A90E50D85500201347 /* time.cc in Sources */, E4AFA4AA0E50D85800201347 /* time_posix.cc in Sources */, diff --git a/base/basictypes.h b/base/basictypes.h index 1de4905..f9e8fe1 100644 --- a/base/basictypes.h +++ b/base/basictypes.h @@ -26,10 +26,9 @@ // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// Copied from base/basictypes.h with some modifications -#ifndef BASE_BASICTYPES_H__ -#define BASE_BASICTYPES_H__ +#ifndef BASE_BASICTYPES_H_ +#define BASE_BASICTYPES_H_ #include <assert.h> // for use with down_cast<> #include <limits.h> // So we can set the bounds of our types @@ -416,7 +415,7 @@ inline Dest bit_cast(const Source& source) { // static MyClass my_variable_name(base::LINKER_INITIALIZED); namespace base { enum LinkerInitialized { LINKER_INITIALIZED }; -} +} // base -#endif // BASE_BASICTYPES_H__ +#endif // BASE_BASICTYPES_H_ diff --git a/base/port.h b/base/port.h index 12b2a90..885e526 100644 --- a/base/port.h +++ b/base/port.h @@ -27,9 +27,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#ifndef BASE_PORT_H__ -#define BASE_PORT_H__ +#ifndef BASE_PORT_H_ +#define BASE_PORT_H_ +#include <stdarg.h> #include "build/build_config.h" #ifdef COMPILER_MSVC @@ -56,4 +57,22 @@ #define GG_UINT32_C(x) (x ## U) #define GG_UINT64_C(x) GG_ULONGLONG(x) -#endif // BASE_PORT_H__ +namespace base { + +// It's possible for functions that use a va_list, such as StringPrintf, to +// invalidate the data in it upon use. The fix is to make a copy of the +// structure before using it and use that copy instead. va_copy is provided +// for this purpose. MSVC does not provide va_copy, so define an +// implementation here. It is not guaranteed that assignment is a copy, so the +// StringUtil.VariableArgsFunc unit test tests this capability. +inline void va_copy(va_list& a, va_list& b) { +#if defined(COMPILER_GCC) + ::va_copy(a, b); +#elif defined(COMPILER_MSVC) + a = b; +#endif +} + +} // namespace base + +#endif // BASE_PORT_H_ diff --git a/base/string_util.cc b/base/string_util.cc index 31f97131b..bd02f3d 100644 --- a/base/string_util.cc +++ b/base/string_util.cc @@ -27,8 +27,6 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// StringPrintf stuff based on strings/stringprintf.cc by Sanjay Ghemawat - #include "base/string_util.h" #include <ctype.h> @@ -47,7 +45,6 @@ #include "base/basictypes.h" #include "base/logging.h" -#include "base/scoped_ptr.h" #include "base/singleton.h" namespace { @@ -763,9 +760,10 @@ void ReplaceSubstringsAfterOffset(std::string* str, // Overloaded wrappers around vsnprintf and vswprintf. The buf_size parameter // is the size of the buffer. These return the number of characters in the -// formatted string excluding the NUL terminator, or if the buffer is not -// large enough to accommodate the formatted string without truncation, the -// number of characters that would be in the fully-formatted string. +// formatted string excluding the NUL terminator. If the buffer is not +// large enough to accommodate the formatted string without truncation, they +// return the number of characters that would be in the fully-formatted string +// (vsnprintf, and vswprintf on Windows), or -1 (vswprintf on POSIX platforms). inline int vsnprintfT(char* buffer, size_t buf_size, const char* format, @@ -789,46 +787,69 @@ static void StringAppendVT( va_list ap) { // First try with a small fixed size buffer. - // This buffer size should be kept in sync with StringUtilTest.GrowBoundary. - const int kStackLength = 1024; - char_type stack_buf[kStackLength]; - - // It's possible for methods that use a va_list to invalidate the data in it - // upon use. The fix is to make a copy of the structure before using it and - // use that copy instead. It is not guaranteed that assignment is a copy, and - // va_copy is not supported by VC, so the UnitTest tests this capability. - va_list backup_ap = ap; - int result = vsnprintfT(stack_buf, kStackLength, format, backup_ap); + // This buffer size should be kept in sync with StringUtilTest.GrowBoundary + // and StringUtilTest.StringPrintfBounds. + char_type stack_buf[1024]; + + va_list backup_ap; + base::va_copy(backup_ap, ap); + +#if !defined(OS_WIN) + errno = 0; +#endif + int result = vsnprintfT(stack_buf, arraysize(stack_buf), format, backup_ap); va_end(backup_ap); - if (result >= 0 && result < kStackLength) { + if (result >= 0 && result < static_cast<int>(arraysize(stack_buf))) { // It fit. dst->append(stack_buf, result); return; } - int mem_length = result; + // Repeatedly increase buffer size until it fits. + int mem_length = arraysize(stack_buf); + while (true) { + if (result < 0) { +#if !defined(OS_WIN) + // On Windows, vsnprintfT always returns the number of characters in a + // fully-formatted string, so if we reach this point, something else is + // wrong and no amount of buffer-doubling is going to fix it. + if (errno != 0 && errno != EOVERFLOW) +#endif + { + // If an error other than overflow occurred, it's never going to work. + DLOG(WARNING) << "Unable to printf the requested string due to error."; + return; + } + // Try doubling the buffer size. + mem_length *= 2; + } else { + // We need exactly "result + 1" characters. + mem_length = result + 1; + } - // vsnprintfT may have failed for some reason other than an insufficient - // buffer, such as an invalid characer. Check that the requested buffer - // size is smaller than what was already attempted - if (mem_length < 0 || mem_length < kStackLength) { - DLOG(WARNING) << "Unable to compute size of the requested string."; - return; - } + if (mem_length > 32 * 1024 * 1024) { + // That should be plenty, don't try anything larger. This protects + // against huge allocations when using vsnprintfT implementations that + // return -1 for reasons other than overflow without setting errno. + DLOG(WARNING) << "Unable to printf the requested string due to size."; + return; + } - mem_length++; // Include the NULL terminator. - scoped_ptr<char_type> mem_buf(new char_type[mem_length]); + std::vector<char_type> mem_buf(mem_length); - // Do the printf. - result = vsnprintfT(mem_buf.get(), mem_length, format, ap); - DCHECK(result < mem_length); - if (result < 0) { - DLOG(WARNING) << "Unable to printf the requested string."; - return; - } + // Restore the va_list before we use it again. + base::va_copy(backup_ap, ap); - dst->append(mem_buf.get(), result); + result = vsnprintfT(&mem_buf[0], mem_length, format, ap); + va_end(backup_ap); + + if ((result >= 0) && (result < mem_length)) { + // It fit. + dst->append(&mem_buf[0], result); + return; + } + } } std::string Uint64ToString(uint64 value) { diff --git a/base/string_util.h b/base/string_util.h index 46269ff..2f0f3d6 100644 --- a/base/string_util.h +++ b/base/string_util.h @@ -53,11 +53,15 @@ namespace base { // s2 > s1 according to a lexicographic comparison. int strncasecmp(const char* s1, const char* s2, size_t count); -// Wrapper for vsnprintf that always NUL-terminates and always returns the +// Wrapper for vsnprintf that always null-terminates and always returns the // number of characters that would be in an untruncated formatted // string, even when truncation occurs. int vsnprintf(char* buffer, size_t size, const char* format, va_list arguments); +// vswprintf always null-terminates, but when truncation occurs, it will either +// return -1 or the number of characters that would be in an untruncated +// formatted string. The actual return value depends on the underlying +// C library's vswprintf implementation. int vswprintf(wchar_t* buffer, size_t size, const wchar_t* format, va_list arguments); diff --git a/base/string_util_icu.cc b/base/string_util_icu.cc index 2ab933a0..fca020b 100644 --- a/base/string_util_icu.cc +++ b/base/string_util_icu.cc @@ -190,7 +190,7 @@ bool WideToUTF8(const wchar_t* src, size_t src_len, std::string* output) { // character, assume the rest will be ASCII and use a buffer size the same as // the input. When it's not ASCII, assume 3-bytes per character as the // starting point. This will be resized internally later if it's too small. - if (src[0] < 0x80) + if (static_cast<uint32>(src[0]) < 0x80) output->reserve(src_len); else output->reserve(src_len * 3); @@ -217,7 +217,7 @@ bool UTF8ToWide(const char* src, size_t src_len, std::wstring* output) { // the input. When it's not ASCII, assume the UTF-8 takes 2 bytes per // character (this is more conservative than 3 which we use above when // converting the other way). - if (src[0] < 0x80) + if (static_cast<unsigned char>(src[0]) < 0x80) output->reserve(src_len); else output->reserve(src_len / 2); @@ -316,7 +316,7 @@ bool WideToCodepage(const std::wstring& wide, #elif defined(WCHAR_T_IS_UTF32) // When wchar_t is wider than UChar (16 bits), transform |wide| into a // UChar* string. Size the UChar* buffer to be large enough to hold twice - // as many UTF-16 code points as there are UCS-4 characters, in case each + // as many UTF-16 code points as there are UTF-16 characters, in case each // character translates to a UTF-16 surrogate pair, and leave room for a NUL // terminator. std::vector<UChar> wide_uchar(wide.length() * 2 + 1); diff --git a/base/string_util_unittest.cc b/base/string_util_unittest.cc index 9b0f9b6..d13107f 100644 --- a/base/string_util_unittest.cc +++ b/base/string_util_unittest.cc @@ -27,9 +27,11 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -#include <sstream> +#include <math.h> #include <stdarg.h> +#include <sstream> + #include "base/basictypes.h" #include "base/logging.h" #include "base/string_util.h" @@ -76,7 +78,7 @@ static const struct trim_case_ascii { TEST(StringUtilTest, TrimWhitespace) { std::wstring output; // Allow contents to carry over to next testcase - for (int i = 0; i < arraysize(trim_cases); ++i) { + for (size_t i = 0; i < arraysize(trim_cases); ++i) { const trim_case& value = trim_cases[i]; EXPECT_EQ(value.return_value, TrimWhitespace(value.input, value.positions, &output)); @@ -94,7 +96,7 @@ TEST(StringUtilTest, TrimWhitespace) { EXPECT_EQ(L"", output); std::string output_ascii; - for (int i = 0; i < arraysize(trim_cases_ascii); ++i) { + for (size_t i = 0; i < arraysize(trim_cases_ascii); ++i) { const trim_case_ascii& value = trim_cases_ascii[i]; EXPECT_EQ(value.return_value, TrimWhitespace(value.input, value.positions, &output_ascii)); @@ -129,7 +131,7 @@ static const struct collapse_case { }; TEST(StringUtilTest, CollapseWhitespace) { - for (int i = 0; i < arraysize(collapse_cases); ++i) { + for (size_t i = 0; i < arraysize(collapse_cases); ++i) { const collapse_case& value = collapse_cases[i]; EXPECT_EQ(value.output, CollapseWhitespace(value.input, value.trim)); } @@ -148,23 +150,25 @@ static const wchar_t* const kConvertRoundtripCases[] = { L"\x0020\x0440\x0443\x0441\x0441\x043a\x043e\x043c", // "전체서비스" L"\xc804\xccb4\xc11c\xbe44\xc2a4", - // ????? (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E) - L"\xd807\xdd40\xd807\xdd41\xd807\xdd42\xd807\xdd43\xd807\xdd44", - // Test a character that takes more than 16-bits. This will depend on whether + // Test characters that take more than 16 bits. This will depend on whether // wchar_t is 16 or 32 bits. - #if defined(WCHAR_T_IS_UTF16) - L"\xd800\xdf00", - #elif defined(WCHAR_T_IS_UTF32) - "\x10300, - #endif +#if defined(WCHAR_T_IS_UTF16) + L"\xd800\xdf00", + // ????? (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E) + L"\xd807\xdd40\xd807\xdd41\xd807\xdd42\xd807\xdd43\xd807\xdd44", +#elif defined(WCHAR_T_IS_UTF32) + L"\x10300", + // ????? (Mathematical Alphanumeric Symbols (U+011d40 - U+011d44 : A,B,C,D,E) + L"\x11d40\x11d41\x11d42\x11d43\x11d44", +#endif }; TEST(StringUtilTest, ConvertUTF8AndWide) { // we round-trip all the wide strings through UTF-8 to make sure everything // agrees on the conversion. This uses the stream operators to test them // simultaneously. - for (int i = 0; i < arraysize(kConvertRoundtripCases); ++i) { + for (size_t i = 0; i < arraysize(kConvertRoundtripCases); ++i) { std::ostringstream utf8; utf8 << WideToUTF8(kConvertRoundtripCases[i]); std::wostringstream wide; @@ -209,7 +213,7 @@ TEST(StringUtilTest, ConvertUTF8ToWide) { #endif }; - for (int i = 0; i < arraysize(convert_cases); i++) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(convert_cases); i++) { std::wstring converted; EXPECT_EQ(convert_cases[i].success, UTF8ToWide(convert_cases[i].utf8, @@ -222,18 +226,18 @@ TEST(StringUtilTest, ConvertUTF8ToWide) { // Manually test an embedded NULL. std::wstring converted; EXPECT_TRUE(UTF8ToWide("\00Z\t", 3, &converted)); - ASSERT_EQ(3, converted.length()); + ASSERT_EQ(static_cast<std::wstring::size_type>(3), converted.length()); EXPECT_EQ(0, converted[0]); EXPECT_EQ('Z', converted[1]); EXPECT_EQ('\t', converted[2]); // Make sure that conversion replaces, not appends. EXPECT_TRUE(UTF8ToWide("B", 1, &converted)); - ASSERT_EQ(1, converted.length()); + ASSERT_EQ(static_cast<std::wstring::size_type>(1), converted.length()); EXPECT_EQ('B', converted[0]); } -#if defined(WCHAR_T_IS_UTf16) +#if defined(WCHAR_T_IS_UTF16) // This test is only valid when wchar_t == UTF-16. TEST(StringUtilTest, ConvertUTF16ToUTF8) { struct UTF16ToUTF8Case { @@ -268,7 +272,7 @@ TEST(StringUtilTest, ConvertUTF16ToUTF8) { // This test is only valid when wchar_t == UTF-32. TEST(StringUtilTest, ConvertUTF32ToUTF8) { struct UTF8ToWideCase { - const wchar_t* ucs4; + const wchar_t* utf32; const char* utf8; bool success; } convert_cases[] = { @@ -277,17 +281,17 @@ TEST(StringUtilTest, ConvertUTF32ToUTF8) { // Test a non-BMP character. {L"A\x10300z", "A\xF0\x90\x8C\x80z", true}, // Invalid Unicode code points. - {L"\xffffHello", "Hello, false", false}, - {L"\xfffffffHello", "Hello, false", false}, + {L"\xffffHello", "Hello", false}, + {L"\xfffffffHello", "Hello", false}, // The first character is a truncated UTF-16 character. {L"\xd800\x597d", "\xe5\xa5\xbd", false}, - } + }; - for (int i = 0; i < arraysize(convert_cases); i++) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(convert_cases); i++) { std::string converted; EXPECT_EQ(convert_cases[i].success, - WideToUTF8(convert_cases[i].utf16, - wcslen(convert_cases[i].utf16), + WideToUTF8(convert_cases[i].utf32, + wcslen(convert_cases[i].utf32), &converted)); std::string expected(convert_cases[i].utf8); EXPECT_EQ(expected, converted); @@ -321,7 +325,7 @@ TEST(StringUtilTest, ConvertMultiString) { TEST(StringUtilTest, ConvertCodepageUTF8) { // Make sure WideToCodepage works like WideToUTF8. - for (int i = 0; i < arraysize(kConvertRoundtripCases); ++i) { + for (size_t i = 0; i < arraysize(kConvertRoundtripCases); ++i) { std::string expected(WideToUTF8(kConvertRoundtripCases[i])); std::string utf8; EXPECT_TRUE(WideToCodepage(kConvertRoundtripCases[i], kCodepageUTF8, @@ -428,7 +432,7 @@ TEST(StringUtilTest, ConvertBetweenCodepageAndWide) { L"\x0E04\x0E23\x0e31\x0E1A"}, }; - for (int i = 0; i < arraysize(kConvertCodepageCases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kConvertCodepageCases); ++i) { std::wstring wide; bool success = CodepageToWide(kConvertCodepageCases[i].encoded, kConvertCodepageCases[i].codepage_name, @@ -470,7 +474,7 @@ TEST(StringUtilTest, ConvertBetweenCodepageAndWide) { EXPECT_TRUE(WideToCodepage(L"a\xd800z", "iso-8859-1", OnStringUtilConversionError::SKIP, &encoded)); EXPECT_STREQ("az", encoded.c_str()); -#endif // WCHAR_T_IS_UTf16 +#endif // WCHAR_T_IS_UTF16 // Invalid characters should fail. EXPECT_TRUE(WideToCodepage(L"a\xffffz", "iso-8859-1", @@ -495,7 +499,7 @@ TEST(StringUtilTest, ConvertASCII) { L"0123ABCDwxyz \a\b\t\r\n!+,.~" }; - for (int i = 0; i < arraysize(char_cases); ++i) { + for (size_t i = 0; i < arraysize(char_cases); ++i) { EXPECT_TRUE(IsStringASCII(char_cases[i])); std::wstring wide = ASCIIToWide(char_cases[i]); EXPECT_EQ(wchar_cases[i], wide); @@ -519,9 +523,11 @@ TEST(StringUtilTest, ConvertASCII) { const int length_with_nul = arraysize(chars_with_nul) - 1; std::string string_with_nul(chars_with_nul, length_with_nul); std::wstring wide_with_nul = ASCIIToWide(string_with_nul); - EXPECT_EQ(length_with_nul, wide_with_nul.length()); + EXPECT_EQ(static_cast<std::wstring::size_type>(length_with_nul), + wide_with_nul.length()); std::string narrow_with_nul = WideToASCII(wide_with_nul); - EXPECT_EQ(length_with_nul, narrow_with_nul.length()); + EXPECT_EQ(static_cast<std::string::size_type>(length_with_nul), + narrow_with_nul.length()); EXPECT_EQ(0, string_with_nul.compare(narrow_with_nul)); } @@ -536,7 +542,7 @@ static const struct { }; TEST(StringUtilTest, LowerCaseEqualsASCII) { - for (int i = 0; i < arraysize(lowercase_cases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(lowercase_cases); ++i) { EXPECT_TRUE(LowerCaseEqualsASCII(lowercase_cases[i].src_w, lowercase_cases[i].dst)); EXPECT_TRUE(LowerCaseEqualsASCII(lowercase_cases[i].src_a, @@ -560,7 +566,7 @@ TEST(StringUtilTest, GetByteDisplayUnits) { #endif }; - for (int i = 0; i < arraysize(cases); ++i) + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) EXPECT_EQ(cases[i].expected, GetByteDisplayUnits(cases[i].bytes)); } @@ -590,7 +596,7 @@ TEST(StringUtilTest, FormatBytes) { #endif }; - for (int i = 0; i < arraysize(cases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { EXPECT_EQ(cases[i].expected, FormatBytes(cases[i].bytes, cases[i].units, false)); EXPECT_EQ(cases[i].expected_with_units, @@ -620,7 +626,7 @@ TEST(StringUtilTest, ReplaceSubstringsAfterOffset) { {L"abababab", 2, L"ab", L"c", L"abccc"}, }; - for (int i = 0; i < arraysize(cases); i++) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); i++) { std::wstring str(cases[i].str); ReplaceSubstringsAfterOffset(&str, cases[i].start_offset, cases[i].find_this, cases[i].replace_with); @@ -640,7 +646,7 @@ TEST(StringUtilTest, IntToString) { {INT_MIN, "-2147483648"}, }; - for (int i = 0; i < arraysize(cases); ++i) + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) EXPECT_EQ(cases[i].output, IntToString(cases[i].input)); } @@ -655,7 +661,7 @@ TEST(StringUtilTest, Uint64ToString) { {kuint64max, "18446744073709551615"}, }; - for (int i = 0; i < arraysize(cases); ++i) + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) EXPECT_EQ(cases[i].output, Uint64ToString(cases[i].input)); } @@ -689,7 +695,7 @@ TEST(StringUtilTest, StringToInt) { {"99999999999", INT_MAX, false}, }; - for (int i = 0; i < arraysize(cases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { EXPECT_EQ(cases[i].output, StringToInt(cases[i].input)); int output; EXPECT_EQ(cases[i].success, StringToInt(cases[i].input, &output)); @@ -753,7 +759,7 @@ TEST(StringUtilTest, StringToInt64) { {"99999999999999999999", kint64max, false}, }; - for (int i = 0; i < arraysize(cases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { EXPECT_EQ(cases[i].output, StringToInt64(cases[i].input)); int64 output; EXPECT_EQ(cases[i].success, StringToInt64(cases[i].input, &output)); @@ -814,7 +820,7 @@ TEST(StringUtilTest, HexStringToInt) { {"", 0, false}, }; - for (int i = 0; i < arraysize(cases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { EXPECT_EQ(cases[i].output, HexStringToInt(cases[i].input)); int output; EXPECT_EQ(cases[i].success, HexStringToInt(cases[i].input, &output)); @@ -874,7 +880,7 @@ TEST(StringUtilTest, StringToDouble) { {"", 0.0, false}, }; - for (int i = 0; i < arraysize(cases); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(cases); ++i) { EXPECT_DOUBLE_EQ(cases[i].output, StringToDouble(cases[i].input)); double output; EXPECT_EQ(cases[i].success, StringToDouble(cases[i].input, &output)); @@ -908,7 +914,8 @@ static void VariableArgsFunc(const char* format, ...) { va_list org; va_start(org, format); - va_list dup = org; + va_list dup; + base::va_copy(dup, org); int i1 = va_arg(org, int); int j1 = va_arg(org, int); char* s1 = va_arg(org, char*); @@ -940,7 +947,7 @@ TEST(StringUtilTest, StringPrintfEmptyFormat) { TEST(StringUtilTest, StringPrintfMisc) { EXPECT_EQ("123hello w", StringPrintf("%3d%2s %1c", 123, "hello", 'w')); - EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2s %1c", 123, L"hello", 'w')); + EXPECT_EQ(L"123hello w", StringPrintf(L"%3d%2ls %1c", 123, L"hello", 'w')); } TEST(StringUtilTest, StringAppendfStringEmptyParam) { @@ -969,7 +976,7 @@ TEST(StringUtilTest, StringAppendfString) { EXPECT_EQ("Hello World", value); std::wstring valuew(L"Hello"); - StringAppendF(&valuew, L" %s", L"World"); + StringAppendF(&valuew, L" %ls", L"World"); EXPECT_EQ(L"Hello World", valuew); } @@ -988,11 +995,11 @@ TEST(StringUtilTest, StringAppendfInt) { TEST(StringUtilTest, StringPrintfBounds) { const int src_len = 1026; char src[src_len]; - for (int i = 0; i < arraysize(src); i++) + for (size_t i = 0; i < arraysize(src); i++) src[i] = 'A'; wchar_t srcw[src_len]; - for (int i = 0; i < arraysize(srcw); i++) + for (size_t i = 0; i < arraysize(srcw); i++) srcw[i] = 'A'; for (int i = 1; i < 3; i++) { @@ -1003,7 +1010,7 @@ TEST(StringUtilTest, StringPrintfBounds) { srcw[src_len - i] = 0; std::wstring outw; - SStringPrintf(&outw, L"%s", srcw); + SStringPrintf(&outw, L"%ls", srcw); EXPECT_STREQ(srcw, outw.c_str()); } } @@ -1011,7 +1018,7 @@ TEST(StringUtilTest, StringPrintfBounds) { // Test very large sprintfs that will cause the buffer to grow. TEST(StringUtilTest, Grow) { char src[1026]; - for (int i = 0; i < arraysize(src); i++) + for (size_t i = 0; i < arraysize(src); i++) src[i] = 'A'; src[1025] = 0; @@ -1021,7 +1028,11 @@ TEST(StringUtilTest, Grow) { SStringPrintf(&out, fmt, src, src, src, src, src, src, src); char* ref = new char[320000]; +#if defined(OS_WIN) sprintf_s(ref, 320000, fmt, src, src, src, src, src, src, src); +#elif defined(OS_POSIX) + snprintf(ref, 320000, fmt, src, src, src, src, src, src, src); +#endif EXPECT_STREQ(ref, out.c_str()); delete ref; @@ -1053,7 +1064,7 @@ TEST(StringUtilTest, Invalid) { invalid[1] = 0; std::wstring out; - SStringPrintf(&out, L"%s", invalid); + SStringPrintf(&out, L"%ls", invalid); EXPECT_STREQ(L"", out.c_str()); } @@ -1062,50 +1073,50 @@ TEST(StringUtilTest, SplitString) { std::vector<std::wstring> r; SplitString(L"a,b,c", L',', &r); - EXPECT_EQ(r.size(), 3); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(3), r.size()); EXPECT_EQ(r[0], L"a"); EXPECT_EQ(r[1], L"b"); EXPECT_EQ(r[2], L"c"); r.clear(); SplitString(L"a, b, c", L',', &r); - EXPECT_EQ(r.size(), 3); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(3), r.size()); EXPECT_EQ(r[0], L"a"); EXPECT_EQ(r[1], L"b"); EXPECT_EQ(r[2], L"c"); r.clear(); SplitString(L"a,,c", L',', &r); - EXPECT_EQ(r.size(), 3); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(3), r.size()); EXPECT_EQ(r[0], L"a"); EXPECT_EQ(r[1], L""); EXPECT_EQ(r[2], L"c"); r.clear(); SplitString(L"", L'*', &r); - EXPECT_EQ(r.size(), 1); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(1), r.size()); EXPECT_EQ(r[0], L""); r.clear(); SplitString(L"foo", L'*', &r); - EXPECT_EQ(r.size(), 1); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(1), r.size()); EXPECT_EQ(r[0], L"foo"); r.clear(); SplitString(L"foo ,", L',', &r); - EXPECT_EQ(r.size(), 2); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(2), r.size()); EXPECT_EQ(r[0], L"foo"); EXPECT_EQ(r[1], L""); r.clear(); SplitString(L",", L',', &r); - EXPECT_EQ(r.size(), 2); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(2), r.size()); EXPECT_EQ(r[0], L""); EXPECT_EQ(r[1], L""); r.clear(); SplitString(L"\t\ta\t", L'\t', &r); - EXPECT_EQ(r.size(), 4); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(4), r.size()); EXPECT_EQ(r[0], L""); EXPECT_EQ(r[1], L""); EXPECT_EQ(r[2], L"a"); @@ -1113,7 +1124,7 @@ TEST(StringUtilTest, SplitString) { r.clear(); SplitStringDontTrim(L"\t\ta\t", L'\t', &r); - EXPECT_EQ(r.size(), 4); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(4), r.size()); EXPECT_EQ(r[0], L""); EXPECT_EQ(r[1], L""); EXPECT_EQ(r[2], L"a"); @@ -1121,13 +1132,13 @@ TEST(StringUtilTest, SplitString) { r.clear(); SplitString(L"\ta\t\nb\tcc", L'\n', &r); - EXPECT_EQ(r.size(), 2); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(2), r.size()); EXPECT_EQ(r[0], L"a"); EXPECT_EQ(r[1], L"b\tcc"); r.clear(); SplitStringDontTrim(L"\ta\t\nb\tcc", L'\n', &r); - EXPECT_EQ(r.size(), 2); + EXPECT_EQ(static_cast<std::vector<std::wstring>::size_type>(2), r.size()); EXPECT_EQ(r[0], L"\ta\t"); EXPECT_EQ(r[1], L"b\tcc"); r.clear(); @@ -1146,16 +1157,16 @@ TEST(StringUtilTest, GetStringFWithOffsets) { ReplaceStringPlaceholders(L"Hello, $1. Your number is $2.", L"1", L"2", &offsets); - EXPECT_EQ(2, offsets.size()); - EXPECT_EQ(7, offsets[0]); - EXPECT_EQ(25, offsets[1]); + EXPECT_EQ(static_cast<std::vector<size_t>::size_type>(2), offsets.size()); + EXPECT_EQ(static_cast<size_t>(7), offsets[0]); + EXPECT_EQ(static_cast<size_t>(25), offsets[1]); offsets.clear(); ReplaceStringPlaceholders(L"Hello, $2. Your number is $1.", L"1", L"2", &offsets); - EXPECT_EQ(2, offsets.size()); - EXPECT_EQ(25, offsets[0]); - EXPECT_EQ(7, offsets[1]); + EXPECT_EQ(static_cast<std::vector<size_t>::size_type>(2), offsets.size()); + EXPECT_EQ(static_cast<size_t>(25), offsets[0]); + EXPECT_EQ(static_cast<size_t>(7), offsets[1]); offsets.clear(); } @@ -1180,10 +1191,12 @@ TEST(StringUtilTest, SplitStringAlongWhitespace) { { L"b\tat", 2, L"b", L"at" }, { L"b\t at", 2, L"b", L"at" }, }; - for (size_t i = 0; i < arraysize(data); ++i) { + for (size_t i = 0; i < ARRAYSIZE_UNSAFE(data); ++i) { std::vector<std::wstring> results; SplitStringAlongWhitespace(data[i].input, &results); - ASSERT_EQ(data[i].expected_result_count, results.size()); + ASSERT_EQ(static_cast<std::vector<std::wstring>::size_type>( + data[i].expected_result_count), + results.size()); if (data[i].expected_result_count > 0) ASSERT_EQ(data[i].output1, results[0]); if (data[i].expected_result_count > 1) |