X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/f68ca36e0d9c7c2549a10ab612aef2e92e7f8be9..d44444105bea5beaab0a39f7624b8ce126dd2384:/src/common/string.cpp diff --git a/src/common/string.cpp b/src/common/string.cpp index b9e30160aa..38351ff5f0 100644 --- a/src/common/string.cpp +++ b/src/common/string.cpp @@ -43,6 +43,10 @@ #include #include +#ifndef __WXMSW__ +#include +#endif + #ifdef __SALFORDC__ #include #endif @@ -312,13 +316,15 @@ bool wxStringBase::AllocBeforeWrite(size_t nLen) pData->nAllocLength = nLen; m_pchData = pData->data(); } - - // now we have enough space, just update the string length - pData->nDataLength = nLen; } wxASSERT( !GetStringData()->IsShared() ); // we must be the only owner + // it doesn't really matter what the string length is as it's going to be + // overwritten later but, for extra safety, set it to 0 for now as we may + // have some junk in m_pchData + GetStringData()->nDataLength = 0; + return true; } @@ -326,7 +332,7 @@ wxStringBase& wxStringBase::append(size_t n, wxChar ch) { size_type len = length(); - if ( !CopyBeforeWrite() || !Alloc(len + n) ) { + if ( !Alloc(len + n) || !CopyBeforeWrite() ) { wxFAIL_MSG( _T("out of memory in wxStringBase::append") ); } GetStringData()->nDataLength = len + n; @@ -380,7 +386,9 @@ bool wxStringBase::Alloc(size_t nLen) // allocation failure handled by caller return false; } - memcpy(m_pchData, pData->data(), nOldLen*sizeof(wxChar)); + // +1 to copy the terminator, too + memcpy(m_pchData, pData->data(), (nOldLen+1)*sizeof(wxChar)); + GetStringData()->nDataLength = nOldLen; } else { nLen += EXTRA_ALLOC; @@ -445,7 +453,7 @@ wxStringBase& wxStringBase::insert(size_t nPos, const wxChar *sz, size_t n) if ( n == npos ) n = wxStrlen(sz); if ( n == 0 ) return *this; - if ( !CopyBeforeWrite() || !Alloc(length() + n) ) { + if ( !Alloc(length() + n) || !CopyBeforeWrite() ) { wxFAIL_MSG( _T("out of memory in wxStringBase::insert") ); } @@ -1225,7 +1233,7 @@ wxString operator+(const wxString& str, const wxChar *psz) if ( !s.Alloc(wxStrlen(psz) + str.Len()) ) { wxFAIL_MSG( _T("out of memory in wxString::operator+") ); } - s = str; + s += str; s += psz; return s; @@ -1788,50 +1796,54 @@ wxString wxString::FormatV(const wxChar *pszFormat, va_list argptr) int wxString::Printf(const wxChar *pszFormat, ...) { - va_list argptr; - va_start(argptr, pszFormat); + va_list argptr; + va_start(argptr, pszFormat); - int iLen = PrintfV(pszFormat, argptr); + int iLen = PrintfV(pszFormat, argptr); - va_end(argptr); + va_end(argptr); - return iLen; + return iLen; } int wxString::PrintfV(const wxChar* pszFormat, va_list argptr) { int size = 1024; - int len; for ( ;; ) { + wxStringBuffer tmp(*this, size + 1); + wxChar* buf = tmp; + + if ( !buf ) { - wxStringBuffer tmp(*this, size + 1); - wxChar* buf = tmp; + // out of memory + return -1; + } - if ( !buf ) - { - // out of memory - return -1; - } + // wxVsnprintf() may modify the original arg pointer, so pass it + // only a copy + va_list argptrcopy; + wxVaCopy(argptrcopy, argptr); + int len = wxVsnprintf(buf, size, pszFormat, argptrcopy); + va_end(argptrcopy); - // wxVsnprintf() may modify the original arg pointer, so pass it - // only a copy - va_list argptrcopy; - wxVaCopy(argptrcopy, argptr); - len = wxVsnprintf(buf, size, pszFormat, argptrcopy); - va_end(argptrcopy); - - // some implementations of vsnprintf() don't NUL terminate - // the string if there is not enough space for it so - // always do it manually - buf[size] = _T('\0'); - } + // some implementations of vsnprintf() don't NUL terminate + // the string if there is not enough space for it so + // always do it manually + buf[size] = _T('\0'); // vsnprintf() may return either -1 (traditional Unix behaviour) or the // total number of characters which would have been written if the // buffer were large enough - if ( len >= 0 && len <= size ) + // also, it may return an errno may be something like EILSEQ, + // in which case we need to break out + if ( (len >= 0 && len <= size) + // No EOVERFLOW on Windows nor Palm 6.0 nor OpenVMS +#if !defined(__WXMSW__) && !defined(__WXPALMOS__) && !defined( __VMS ) + || errno != EOVERFLOW +#endif + ) { // ok, there was enough space break;