1*9712c20fSFrederick Mayle // Copyright 2006 Google LLC
2*9712c20fSFrederick Mayle //
3*9712c20fSFrederick Mayle // Redistribution and use in source and binary forms, with or without
4*9712c20fSFrederick Mayle // modification, are permitted provided that the following conditions are
5*9712c20fSFrederick Mayle // met:
6*9712c20fSFrederick Mayle //
7*9712c20fSFrederick Mayle // * Redistributions of source code must retain the above copyright
8*9712c20fSFrederick Mayle // notice, this list of conditions and the following disclaimer.
9*9712c20fSFrederick Mayle // * Redistributions in binary form must reproduce the above
10*9712c20fSFrederick Mayle // copyright notice, this list of conditions and the following disclaimer
11*9712c20fSFrederick Mayle // in the documentation and/or other materials provided with the
12*9712c20fSFrederick Mayle // distribution.
13*9712c20fSFrederick Mayle // * Neither the name of Google LLC nor the names of its
14*9712c20fSFrederick Mayle // contributors may be used to endorse or promote products derived from
15*9712c20fSFrederick Mayle // this software without specific prior written permission.
16*9712c20fSFrederick Mayle //
17*9712c20fSFrederick Mayle // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*9712c20fSFrederick Mayle // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*9712c20fSFrederick Mayle // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*9712c20fSFrederick Mayle // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*9712c20fSFrederick Mayle // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*9712c20fSFrederick Mayle // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*9712c20fSFrederick Mayle // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*9712c20fSFrederick Mayle // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*9712c20fSFrederick Mayle // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*9712c20fSFrederick Mayle // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*9712c20fSFrederick Mayle // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*9712c20fSFrederick Mayle
29*9712c20fSFrederick Mayle // string_utils-inl.h: Safer string manipulation on Windows, supporting
30*9712c20fSFrederick Mayle // pre-MSVC8 environments.
31*9712c20fSFrederick Mayle
32*9712c20fSFrederick Mayle #ifndef COMMON_WINDOWS_STRING_UTILS_INL_H_
33*9712c20fSFrederick Mayle #define COMMON_WINDOWS_STRING_UTILS_INL_H_
34*9712c20fSFrederick Mayle
35*9712c20fSFrederick Mayle #include <stdarg.h>
36*9712c20fSFrederick Mayle #include <wchar.h>
37*9712c20fSFrederick Mayle
38*9712c20fSFrederick Mayle #include <string>
39*9712c20fSFrederick Mayle
40*9712c20fSFrederick Mayle // The "ll" printf format size specifier corresponding to |long long| was
41*9712c20fSFrederick Mayle // intrudced in MSVC8. Earlier versions did not provide this size specifier,
42*9712c20fSFrederick Mayle // but "I64" can be used to print 64-bit types. Don't use "I64" where "ll"
43*9712c20fSFrederick Mayle // is available, in the event of oddball systems where |long long| is not
44*9712c20fSFrederick Mayle // 64 bits wide.
45*9712c20fSFrederick Mayle #if _MSC_VER >= 1400 // MSVC 2005/8
46*9712c20fSFrederick Mayle #define WIN_STRING_FORMAT_LL "ll"
47*9712c20fSFrederick Mayle #else // MSC_VER >= 1400
48*9712c20fSFrederick Mayle #define WIN_STRING_FORMAT_LL "I64"
49*9712c20fSFrederick Mayle #endif // MSC_VER >= 1400
50*9712c20fSFrederick Mayle
51*9712c20fSFrederick Mayle // A nonconforming version of swprintf, without the length argument, was
52*9712c20fSFrederick Mayle // included with the CRT prior to MSVC8. Although a conforming version was
53*9712c20fSFrederick Mayle // also available via an overload, it is not reliably chosen. _snwprintf
54*9712c20fSFrederick Mayle // behaves as a standards-confirming swprintf should, so force the use of
55*9712c20fSFrederick Mayle // _snwprintf when using older CRTs.
56*9712c20fSFrederick Mayle #if _MSC_VER < 1400 // MSVC 2005/8
57*9712c20fSFrederick Mayle #define swprintf _snwprintf
58*9712c20fSFrederick Mayle #else
59*9712c20fSFrederick Mayle // For MSVC8 and newer, swprintf_s is the recommended method. Conveniently,
60*9712c20fSFrederick Mayle // it takes the same argument list as swprintf.
61*9712c20fSFrederick Mayle #define swprintf swprintf_s
62*9712c20fSFrederick Mayle #endif // MSC_VER < 1400
63*9712c20fSFrederick Mayle
64*9712c20fSFrederick Mayle namespace google_breakpad {
65*9712c20fSFrederick Mayle
66*9712c20fSFrederick Mayle using std::string;
67*9712c20fSFrederick Mayle using std::wstring;
68*9712c20fSFrederick Mayle
69*9712c20fSFrederick Mayle class WindowsStringUtils {
70*9712c20fSFrederick Mayle public:
71*9712c20fSFrederick Mayle // Roughly equivalent to MSVC8's wcscpy_s, except pre-MSVC8, this does
72*9712c20fSFrederick Mayle // not fail if source is longer than destination_size. The destination
73*9712c20fSFrederick Mayle // buffer is always 0-terminated.
74*9712c20fSFrederick Mayle static void safe_wcscpy(wchar_t* destination, size_t destination_size,
75*9712c20fSFrederick Mayle const wchar_t* source);
76*9712c20fSFrederick Mayle
77*9712c20fSFrederick Mayle // Roughly equivalent to MSVC8's wcsncpy_s, except that _TRUNCATE cannot
78*9712c20fSFrederick Mayle // be passed directly, and pre-MSVC8, this will not fail if source or count
79*9712c20fSFrederick Mayle // are longer than destination_size. The destination buffer is always
80*9712c20fSFrederick Mayle // 0-terminated.
81*9712c20fSFrederick Mayle static void safe_wcsncpy(wchar_t* destination, size_t destination_size,
82*9712c20fSFrederick Mayle const wchar_t* source, size_t count);
83*9712c20fSFrederick Mayle
84*9712c20fSFrederick Mayle // Performs multi-byte to wide character conversion on C++ strings, using
85*9712c20fSFrederick Mayle // mbstowcs_s (MSVC8) or mbstowcs (pre-MSVC8). Returns false on failure,
86*9712c20fSFrederick Mayle // without setting wcs.
87*9712c20fSFrederick Mayle static bool safe_mbstowcs(const string& mbs, wstring* wcs);
88*9712c20fSFrederick Mayle
89*9712c20fSFrederick Mayle // The inverse of safe_mbstowcs.
90*9712c20fSFrederick Mayle static bool safe_wcstombs(const wstring& wcs, string* mbs);
91*9712c20fSFrederick Mayle
92*9712c20fSFrederick Mayle // Returns the base name of a file, e.g. strips off the path.
93*9712c20fSFrederick Mayle static wstring GetBaseName(const wstring& filename);
94*9712c20fSFrederick Mayle
95*9712c20fSFrederick Mayle private:
96*9712c20fSFrederick Mayle // Disallow instantiation and other object-based operations.
97*9712c20fSFrederick Mayle WindowsStringUtils();
98*9712c20fSFrederick Mayle WindowsStringUtils(const WindowsStringUtils&);
99*9712c20fSFrederick Mayle ~WindowsStringUtils();
100*9712c20fSFrederick Mayle void operator=(const WindowsStringUtils&);
101*9712c20fSFrederick Mayle };
102*9712c20fSFrederick Mayle
103*9712c20fSFrederick Mayle // static
safe_wcscpy(wchar_t * destination,size_t destination_size,const wchar_t * source)104*9712c20fSFrederick Mayle inline void WindowsStringUtils::safe_wcscpy(wchar_t* destination,
105*9712c20fSFrederick Mayle size_t destination_size,
106*9712c20fSFrederick Mayle const wchar_t* source) {
107*9712c20fSFrederick Mayle #if _MSC_VER >= 1400 // MSVC 2005/8
108*9712c20fSFrederick Mayle wcscpy_s(destination, destination_size, source);
109*9712c20fSFrederick Mayle #else // _MSC_VER >= 1400
110*9712c20fSFrederick Mayle // Pre-MSVC 2005/8 doesn't have wcscpy_s. Simulate it with wcsncpy.
111*9712c20fSFrederick Mayle // wcsncpy doesn't 0-terminate the destination buffer if the source string
112*9712c20fSFrederick Mayle // is longer than size. Ensure that the destination is 0-terminated.
113*9712c20fSFrederick Mayle wcsncpy(destination, source, destination_size);
114*9712c20fSFrederick Mayle if (destination && destination_size)
115*9712c20fSFrederick Mayle destination[destination_size - 1] = 0;
116*9712c20fSFrederick Mayle #endif // _MSC_VER >= 1400
117*9712c20fSFrederick Mayle }
118*9712c20fSFrederick Mayle
119*9712c20fSFrederick Mayle // static
safe_wcsncpy(wchar_t * destination,size_t destination_size,const wchar_t * source,size_t count)120*9712c20fSFrederick Mayle inline void WindowsStringUtils::safe_wcsncpy(wchar_t* destination,
121*9712c20fSFrederick Mayle size_t destination_size,
122*9712c20fSFrederick Mayle const wchar_t* source,
123*9712c20fSFrederick Mayle size_t count) {
124*9712c20fSFrederick Mayle #if _MSC_VER >= 1400 // MSVC 2005/8
125*9712c20fSFrederick Mayle wcsncpy_s(destination, destination_size, source, count);
126*9712c20fSFrederick Mayle #else // _MSC_VER >= 1400
127*9712c20fSFrederick Mayle // Pre-MSVC 2005/8 doesn't have wcsncpy_s. Simulate it with wcsncpy.
128*9712c20fSFrederick Mayle // wcsncpy doesn't 0-terminate the destination buffer if the source string
129*9712c20fSFrederick Mayle // is longer than size. Ensure that the destination is 0-terminated.
130*9712c20fSFrederick Mayle if (destination_size < count)
131*9712c20fSFrederick Mayle count = destination_size;
132*9712c20fSFrederick Mayle
133*9712c20fSFrederick Mayle wcsncpy(destination, source, count);
134*9712c20fSFrederick Mayle if (destination && count)
135*9712c20fSFrederick Mayle destination[count - 1] = 0;
136*9712c20fSFrederick Mayle #endif // _MSC_VER >= 1400
137*9712c20fSFrederick Mayle }
138*9712c20fSFrederick Mayle
139*9712c20fSFrederick Mayle } // namespace google_breakpad
140*9712c20fSFrederick Mayle
141*9712c20fSFrederick Mayle #endif // COMMON_WINDOWS_STRING_UTILS_INL_H_
142