xref: /aosp_15_r20/external/google-breakpad/src/common/windows/string_utils.cc (revision 9712c20fc9bbfbac4935993a2ca0b3958c5adad2)
1 // Copyright 2006 Google LLC
2 //
3 // Redistribution and use in source and binary forms, with or without
4 // modification, are permitted provided that the following conditions are
5 // met:
6 //
7 //     * Redistributions of source code must retain the above copyright
8 // notice, this list of conditions and the following disclaimer.
9 //     * Redistributions in binary form must reproduce the above
10 // copyright notice, this list of conditions and the following disclaimer
11 // in the documentation and/or other materials provided with the
12 // distribution.
13 //     * Neither the name of Google LLC nor the names of its
14 // contributors may be used to endorse or promote products derived from
15 // this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>  // Must come first
31 #endif
32 
33 #include <cassert>
34 #include <vector>
35 
36 #include "common/windows/string_utils-inl.h"
37 
38 namespace google_breakpad {
39 
40 // static
GetBaseName(const wstring & filename)41 wstring WindowsStringUtils::GetBaseName(const wstring& filename) {
42   wstring base_name(filename);
43   size_t slash_pos = base_name.find_last_of(L"/\\");
44   if (slash_pos != wstring::npos) {
45     base_name.erase(0, slash_pos + 1);
46   }
47   return base_name;
48 }
49 
50 // static
safe_mbstowcs(const string & mbs,wstring * wcs)51 bool WindowsStringUtils::safe_mbstowcs(const string& mbs, wstring* wcs) {
52   assert(wcs);
53 
54   // First, determine the length of the destination buffer.
55   size_t wcs_length;
56 
57 #if _MSC_VER >= 1400  // MSVC 2005/8
58   errno_t err;
59   if ((err = mbstowcs_s(&wcs_length, NULL, 0, mbs.c_str(), _TRUNCATE)) != 0) {
60     return false;
61   }
62   assert(wcs_length > 0);
63 #else  // _MSC_VER >= 1400
64   if ((wcs_length = mbstowcs(NULL, mbs.c_str(), mbs.length())) == (size_t)-1) {
65     return false;
66   }
67 
68   // Leave space for the 0-terminator.
69   ++wcs_length;
70 #endif  // _MSC_VER >= 1400
71 
72   std::vector<wchar_t> wcs_v(wcs_length);
73 
74   // Now, convert.
75 #if _MSC_VER >= 1400  // MSVC 2005/8
76   if ((err = mbstowcs_s(NULL, &wcs_v[0], wcs_length, mbs.c_str(),
77                         _TRUNCATE)) != 0) {
78     return false;
79   }
80 #else  // _MSC_VER >= 1400
81   if (mbstowcs(&wcs_v[0], mbs.c_str(), mbs.length()) == (size_t)-1) {
82     return false;
83   }
84 
85   // Ensure presence of 0-terminator.
86   wcs_v[wcs_length - 1] = '\0';
87 #endif  // _MSC_VER >= 1400
88 
89   *wcs = &wcs_v[0];
90   return true;
91 }
92 
93 // static
safe_wcstombs(const wstring & wcs,string * mbs)94 bool WindowsStringUtils::safe_wcstombs(const wstring& wcs, string* mbs) {
95   assert(mbs);
96 
97   // First, determine the length of the destination buffer.
98   size_t mbs_length;
99 
100 #if _MSC_VER >= 1400  // MSVC 2005/8
101   errno_t err;
102   if ((err = wcstombs_s(&mbs_length, NULL, 0, wcs.c_str(), _TRUNCATE)) != 0) {
103     return false;
104   }
105   assert(mbs_length > 0);
106 #else  // _MSC_VER >= 1400
107   if ((mbs_length = wcstombs(NULL, wcs.c_str(), wcs.length())) == (size_t)-1) {
108     return false;
109   }
110 
111   // Leave space for the 0-terminator.
112   ++mbs_length;
113 #endif  // _MSC_VER >= 1400
114 
115   std::vector<char> mbs_v(mbs_length);
116 
117   // Now, convert.
118 #if _MSC_VER >= 1400  // MSVC 2005/8
119   if ((err = wcstombs_s(NULL, &mbs_v[0], mbs_length, wcs.c_str(),
120                         _TRUNCATE)) != 0) {
121     return false;
122   }
123 #else  // _MSC_VER >= 1400
124   if (wcstombs(&mbs_v[0], wcs.c_str(), wcs.length()) == (size_t)-1) {
125     return false;
126   }
127 
128   // Ensure presence of 0-terminator.
129   mbs_v[mbs_length - 1] = '\0';
130 #endif  // _MSC_VER >= 1400
131 
132   *mbs = &mbs_v[0];
133   return true;
134 }
135 
136 }  // namespace google_breakpad
137