173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// Copyright (c) 2006, Google Inc.
273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// All rights reserved.
373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai//
473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// Redistribution and use in source and binary forms, with or without
573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// modification, are permitted provided that the following conditions are
673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// met:
773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai//
873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai//     * Redistributions of source code must retain the above copyright
973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// notice, this list of conditions and the following disclaimer.
1073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai//     * Redistributions in binary form must reproduce the above
1173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// copyright notice, this list of conditions and the following disclaimer
1273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// in the documentation and/or other materials provided with the
1373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// distribution.
1473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai//     * Neither the name of Google Inc. nor the names of its
1573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// contributors may be used to endorse or promote products derived from
1673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// this software without specific prior written permission.
1773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai//
1873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
3073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// string_utils-inl.h: Safer string manipulation on Windows, supporting
3173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// pre-MSVC8 environments.
3273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
330a35290a4ecafc23215c2df491f7093f18fcda97ivan.penkov@gmail.com#ifndef COMMON_WINDOWS_STRING_UTILS_INL_H_
340a35290a4ecafc23215c2df491f7093f18fcda97ivan.penkov@gmail.com#define COMMON_WINDOWS_STRING_UTILS_INL_H_
3573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
3673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#include <stdarg.h>
3773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#include <wchar.h>
3873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
3993fa375b580a647904925cb741266f2d679cb448mmentovai#include <string>
4093fa375b580a647904925cb741266f2d679cb448mmentovai
4173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// The "ll" printf format size specifier corresponding to |long long| was
4273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// intrudced in MSVC8.  Earlier versions did not provide this size specifier,
4373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// but "I64" can be used to print 64-bit types.  Don't use "I64" where "ll"
4473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// is available, in the event of oddball systems where |long long| is not
4573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// 64 bits wide.
4673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#if _MSC_VER >= 1400  // MSVC 2005/8
4773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#define WIN_STRING_FORMAT_LL "ll"
4873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#else  // MSC_VER >= 1400
4973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#define WIN_STRING_FORMAT_LL "I64"
5073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#endif  // MSC_VER >= 1400
5173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
5229789d8106fb3beb6626be614d7c8819d4f561a7mmentovai// A nonconforming version of swprintf, without the length argument, was
5329789d8106fb3beb6626be614d7c8819d4f561a7mmentovai// included with the CRT prior to MSVC8.  Although a conforming version was
5429789d8106fb3beb6626be614d7c8819d4f561a7mmentovai// also available via an overload, it is not reliably chosen.  _snwprintf
5529789d8106fb3beb6626be614d7c8819d4f561a7mmentovai// behaves as a standards-confirming swprintf should, so force the use of
5629789d8106fb3beb6626be614d7c8819d4f561a7mmentovai// _snwprintf when using older CRTs.
5729789d8106fb3beb6626be614d7c8819d4f561a7mmentovai#if _MSC_VER < 1400  // MSVC 2005/8
5829789d8106fb3beb6626be614d7c8819d4f561a7mmentovai#define swprintf _snwprintf
59c1e0783204d2787932e4f1d6855866ad57209053ted.mielczarek#else
60c1e0783204d2787932e4f1d6855866ad57209053ted.mielczarek// For MSVC8 and newer, swprintf_s is the recommended method. Conveniently,
61c1e0783204d2787932e4f1d6855866ad57209053ted.mielczarek// it takes the same argument list as swprintf.
62c1e0783204d2787932e4f1d6855866ad57209053ted.mielczarek#define swprintf swprintf_s
6329789d8106fb3beb6626be614d7c8819d4f561a7mmentovai#endif  // MSC_VER < 1400
6429789d8106fb3beb6626be614d7c8819d4f561a7mmentovai
65e5dc60822e5938fea2ae892ccddb906641ba174emmentovainamespace google_breakpad {
6673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
6750e299b00e803f085b34847dfe5232b471d84197mmentovaiusing std::string;
6893fa375b580a647904925cb741266f2d679cb448mmentovaiusing std::wstring;
6993fa375b580a647904925cb741266f2d679cb448mmentovai
7073cd14b4af906e77f3d8b019962fb9979ff12620mmentovaiclass WindowsStringUtils {
7173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai public:
7273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // Roughly equivalent to MSVC8's wcscpy_s, except pre-MSVC8, this does
7373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // not fail if source is longer than destination_size.  The destination
7473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // buffer is always 0-terminated.
7573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  static void safe_wcscpy(wchar_t *destination, size_t destination_size,
7673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                          const wchar_t *source);
7773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
7873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // Roughly equivalent to MSVC8's wcsncpy_s, except that _TRUNCATE cannot
7973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // be passed directly, and pre-MSVC8, this will not fail if source or count
8073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // are longer than destination_size.  The destination buffer is always
8173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // 0-terminated.
8273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  static void safe_wcsncpy(wchar_t *destination, size_t destination_size,
8373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                           const wchar_t *source, size_t count);
8473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
8550e299b00e803f085b34847dfe5232b471d84197mmentovai  // Performs multi-byte to wide character conversion on C++ strings, using
8650e299b00e803f085b34847dfe5232b471d84197mmentovai  // mbstowcs_s (MSVC8) or mbstowcs (pre-MSVC8).  Returns false on failure,
8750e299b00e803f085b34847dfe5232b471d84197mmentovai  // without setting wcs.
8850e299b00e803f085b34847dfe5232b471d84197mmentovai  static bool safe_mbstowcs(const string &mbs, wstring *wcs);
8950e299b00e803f085b34847dfe5232b471d84197mmentovai
90d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  // The inverse of safe_mbstowcs.
91d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek  static bool safe_wcstombs(const wstring &wcs, string *mbs);
92d35f113d020aa1cb4f18aace03eca4eb8705dad2ted.mielczarek
9393fa375b580a647904925cb741266f2d679cb448mmentovai  // Returns the base name of a file, e.g. strips off the path.
9493fa375b580a647904925cb741266f2d679cb448mmentovai  static wstring GetBaseName(const wstring &filename);
9593fa375b580a647904925cb741266f2d679cb448mmentovai
9673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai private:
9773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // Disallow instantiation and other object-based operations.
9873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  WindowsStringUtils();
9973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  WindowsStringUtils(const WindowsStringUtils&);
10073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  ~WindowsStringUtils();
10173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  void operator=(const WindowsStringUtils&);
10273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai};
10373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
10473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// static
10573cd14b4af906e77f3d8b019962fb9979ff12620mmentovaiinline void WindowsStringUtils::safe_wcscpy(wchar_t *destination,
10673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                                            size_t destination_size,
10773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                                            const wchar_t *source) {
10873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#if _MSC_VER >= 1400  // MSVC 2005/8
10973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  wcscpy_s(destination, destination_size, source);
11073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#else  // _MSC_VER >= 1400
11173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // Pre-MSVC 2005/8 doesn't have wcscpy_s.  Simulate it with wcsncpy.
11273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // wcsncpy doesn't 0-terminate the destination buffer if the source string
11373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // is longer than size.  Ensure that the destination is 0-terminated.
11473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  wcsncpy(destination, source, destination_size);
11573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  if (destination && destination_size)
11673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai    destination[destination_size - 1] = 0;
11773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#endif  // _MSC_VER >= 1400
11873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai}
11973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
12073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai// static
12173cd14b4af906e77f3d8b019962fb9979ff12620mmentovaiinline void WindowsStringUtils::safe_wcsncpy(wchar_t *destination,
12273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                                             size_t destination_size,
12373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                                             const wchar_t *source,
12473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai                                             size_t count) {
12573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#if _MSC_VER >= 1400  // MSVC 2005/8
12673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  wcsncpy_s(destination, destination_size, source, count);
12773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#else  // _MSC_VER >= 1400
12873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // Pre-MSVC 2005/8 doesn't have wcsncpy_s.  Simulate it with wcsncpy.
12973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // wcsncpy doesn't 0-terminate the destination buffer if the source string
13073cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  // is longer than size.  Ensure that the destination is 0-terminated.
13173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  if (destination_size < count)
13273cd14b4af906e77f3d8b019962fb9979ff12620mmentovai    count = destination_size;
13373cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
13473cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  wcsncpy(destination, source, count);
13573cd14b4af906e77f3d8b019962fb9979ff12620mmentovai  if (destination && count)
13673cd14b4af906e77f3d8b019962fb9979ff12620mmentovai    destination[count - 1] = 0;
13773cd14b4af906e77f3d8b019962fb9979ff12620mmentovai#endif  // _MSC_VER >= 1400
13873cd14b4af906e77f3d8b019962fb9979ff12620mmentovai}
13973cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
140e5dc60822e5938fea2ae892ccddb906641ba174emmentovai}  // namespace google_breakpad
14173cd14b4af906e77f3d8b019962fb9979ff12620mmentovai
1420a35290a4ecafc23215c2df491f7093f18fcda97ivan.penkov@gmail.com#endif  // COMMON_WINDOWS_STRING_UTILS_INL_H_
143