From 1a0b69436c98d3db15c8c83f8ac2881c50621cc1 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Thu, 3 Sep 2009 00:32:09 +0000 Subject: [PATCH] Fix off by one errors and buffer overflows in wxURLDataObject. Backport of r61787 and r61788 from trunk. Closes #11102. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@61814 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/msw/ole/dataobj.cpp | 68 ++++++++++++++++++++++++----------------- 1 file changed, 40 insertions(+), 28 deletions(-) diff --git a/src/msw/ole/dataobj.cpp b/src/msw/ole/dataobj.cpp index 20a3d633fc..d92e713a18 100644 --- a/src/msw/ole/dataobj.cpp +++ b/src/msw/ole/dataobj.cpp @@ -1196,24 +1196,7 @@ public: return buffer; } -#if wxUSE_UNICODE - virtual bool GetDataHere( void* buffer ) const - { - // CFSTR_SHELLURL is _always_ ANSI! - wxCharBuffer char_buffer( GetDataSize() ); - wxCustomDataObject::GetDataHere( (void*)char_buffer.data() ); - wxString unicode_buffer( char_buffer, wxConvLibc ); - memcpy( buffer, unicode_buffer.c_str(), - ( unicode_buffer.length() + 1 ) * sizeof(wxChar) ); - - return true; - } - virtual bool GetDataHere(const wxDataFormat& WXUNUSED(format), - void *buf) const - { return GetDataHere(buf); } -#endif - - DECLARE_NO_COPY_CLASS(CFSTR_SHELLURLDataObject) + wxDECLARE_NO_COPY_CLASS(CFSTR_SHELLURLDataObject); }; @@ -1248,28 +1231,57 @@ bool wxURLDataObject::SetData(const wxDataFormat& format, wxString wxURLDataObject::GetURL() const { wxString url; - wxCHECK_MSG( m_dataObjectLast, url, _T("no data in wxURLDataObject") ); + wxCHECK_MSG( m_dataObjectLast, url, wxT("no data in wxURLDataObject") ); - size_t len = m_dataObjectLast->GetDataSize(); + if ( m_dataObjectLast->GetPreferredFormat() == CFSTR_SHELLURL ) + { + const size_t len = m_dataObjectLast->GetDataSize(); + if ( !len ) + return wxString(); - m_dataObjectLast->GetDataHere(wxStringBuffer(url, len)); + // CFSTR_SHELLURL is always ANSI so we need to convert it from it in + // Unicode build +#if wxUSE_UNICODE + wxCharBuffer buf(len); + + if ( m_dataObjectLast->GetDataHere(buf.data()) ) + url = buf; +#else // !wxUSE_UNICODE + // in ANSI build no conversion is necessary + m_dataObjectLast->GetDataHere(wxStringBuffer(url, len)); +#endif // wxUSE_UNICODE/!wxUSE_UNICODE + } + else // must be wxTextDataObject + { + url = static_cast(m_dataObjectLast)->GetText(); + } return url; } void wxURLDataObject::SetURL(const wxString& url) { - SetData(wxDataFormat(wxUSE_UNICODE ? wxDF_UNICODETEXT : wxDF_TEXT), - url.Length()+1, url.c_str()); - // CFSTR_SHELLURL is always supposed to be ANSI... - wxWX2MBbuf urlA = (wxWX2MBbuf)url.mbc_str(); + wxWX2MBbuf urlMB = (wxWX2MBbuf)url.mbc_str(); if ( urlA ) { - size_t len = strlen(urlA); - SetData(wxDataFormat(CFSTR_SHELLURL), len+1, (const char*)urlA); + const size_t len = strlen(urlMB); + +#if !wxUSE_UNICODE + // wxTextDataObject takes the number of characters in the string, not + // the size of the buffer (which would be len+1) + SetData(wxDF_TEXT, len, urlMB); +#endif // !wxUSE_UNICODE + + // however CFSTR_SHELLURLDataObject doesn't append NUL automatically + // but we probably still want to have it on the clipboard (just to be + // safe), so do append it + SetData(wxDataFormat(CFSTR_SHELLURL), len + 1, urlMB); } - //else: we can't represent this URL in the current code page + +#if wxUSE_UNICODE + SetData(wxDF_UNICODETEXT, url.length()*sizeof(wxChar), url.wc_str()); +#endif } // ----------------------------------------------------------------------------