1 // Copyright 2010 The Chromium Authors 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifdef UNSAFE_BUFFERS_BUILD 6 // TODO(crbug.com/40284755): Remove this and spanify to fix the errors. 7 #pragma allow_unsafe_buffers 8 #endif 9 10 #include "base/win/scoped_bstr.h" 11 12 #include <stdint.h> 13 14 #include <string_view> 15 16 #include "base/check.h" 17 #include "base/numerics/safe_conversions.h" 18 #include "base/process/memory.h" 19 #include "base/strings/string_util.h" 20 21 namespace base { 22 namespace win { 23 24 namespace { 25 AllocBstrOrDie(std::wstring_view non_bstr)26BSTR AllocBstrOrDie(std::wstring_view non_bstr) { 27 BSTR result = ::SysAllocStringLen(non_bstr.data(), 28 checked_cast<UINT>(non_bstr.length())); 29 if (!result) { 30 base::TerminateBecauseOutOfMemory((non_bstr.length() + 1) * 31 sizeof(wchar_t)); 32 } 33 return result; 34 } 35 AllocBstrBytesOrDie(size_t bytes)36BSTR AllocBstrBytesOrDie(size_t bytes) { 37 BSTR result = ::SysAllocStringByteLen(nullptr, checked_cast<UINT>(bytes)); 38 if (!result) 39 base::TerminateBecauseOutOfMemory(bytes + sizeof(wchar_t)); 40 return result; 41 } 42 43 } // namespace 44 ScopedBstr(std::wstring_view non_bstr)45ScopedBstr::ScopedBstr(std::wstring_view non_bstr) 46 : bstr_(AllocBstrOrDie(non_bstr)) {} 47 ~ScopedBstr()48ScopedBstr::~ScopedBstr() { 49 static_assert(sizeof(ScopedBstr) == sizeof(BSTR), "ScopedBstrSize"); 50 ::SysFreeString(bstr_); 51 } 52 Reset(BSTR bstr)53void ScopedBstr::Reset(BSTR bstr) { 54 if (bstr != bstr_) { 55 // SysFreeString handles null properly. 56 ::SysFreeString(bstr_); 57 bstr_ = bstr; 58 } 59 } 60 Release()61BSTR ScopedBstr::Release() { 62 BSTR bstr = bstr_; 63 bstr_ = nullptr; 64 return bstr; 65 } 66 Swap(ScopedBstr & bstr2)67void ScopedBstr::Swap(ScopedBstr& bstr2) { 68 BSTR tmp = bstr_; 69 bstr_ = bstr2.bstr_; 70 bstr2.bstr_ = tmp; 71 } 72 Receive()73BSTR* ScopedBstr::Receive() { 74 DCHECK(!bstr_) << "BSTR leak."; 75 return &bstr_; 76 } 77 Allocate(std::wstring_view str)78BSTR ScopedBstr::Allocate(std::wstring_view str) { 79 Reset(AllocBstrOrDie(str)); 80 return bstr_; 81 } 82 AllocateBytes(size_t bytes)83BSTR ScopedBstr::AllocateBytes(size_t bytes) { 84 Reset(AllocBstrBytesOrDie(bytes)); 85 return bstr_; 86 } 87 SetByteLen(size_t bytes)88void ScopedBstr::SetByteLen(size_t bytes) { 89 DCHECK(bstr_); 90 uint32_t* data = reinterpret_cast<uint32_t*>(bstr_); 91 data[-1] = checked_cast<uint32_t>(bytes); 92 } 93 Length() const94size_t ScopedBstr::Length() const { 95 return ::SysStringLen(bstr_); 96 } 97 ByteLength() const98size_t ScopedBstr::ByteLength() const { 99 return ::SysStringByteLen(bstr_); 100 } 101 102 } // namespace win 103 } // namespace base 104