reverted the change of r56246 and keep the old behaviour of MB2WC/WC2MB; document it even more clearly and correct code using these functions incorrectly

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_8_BRANCH@56394 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2008-10-17 11:31:22 +00:00
parent 2471348611
commit 753874333a
5 changed files with 36 additions and 34 deletions

View File

@@ -91,10 +91,6 @@ Major new features in 2.8 release
2.8.10: 2.8.10:
------- -------
All:
- Fixed off by one bug in wxMBConv::MB2WC/WC2MB() functions.
All (GUI): All (GUI):
- Fixed wxHTML's pagebreaks computation in tables (D.J.Stauffer). - Fixed wxHTML's pagebreaks computation in tables (D.J.Stauffer).
@@ -110,6 +106,7 @@ All (Unix):
wxMSW: wxMSW:
- Fixed bug with using non default encoding in wxTextCtrl in ANSI build.
- Restored generation of events for accelerators when there is no menu bar. - Restored generation of events for accelerators when there is no menu bar.
- Fixed wxArtProvider::GetSizeHint() to return 16x16 for wxART_FRAME_ICON. - Fixed wxArtProvider::GetSizeHint() to return 16x16 for wxART_FRAME_ICON.

View File

@@ -332,9 +332,7 @@ wxMBConv::FromWChar(char *dst, size_t dstLen,
size_t wxMBConv::MB2WC(wchar_t *outBuff, const char *inBuff, size_t outLen) const size_t wxMBConv::MB2WC(wchar_t *outBuff, const char *inBuff, size_t outLen) const
{ {
// add 1 to available buffer length because MB2WC() parameter counts the size_t rc = ToWChar(outBuff, outLen, inBuff);
// number of non-NUL characters while ToWChar() counts everything
size_t rc = ToWChar(outBuff, outLen + 1, inBuff);
if ( rc != wxCONV_FAILED ) if ( rc != wxCONV_FAILED )
{ {
// ToWChar() returns the buffer length, i.e. including the trailing // ToWChar() returns the buffer length, i.e. including the trailing
@@ -347,12 +345,10 @@ size_t wxMBConv::MB2WC(wchar_t *outBuff, const char *inBuff, size_t outLen) cons
size_t wxMBConv::WC2MB(char *outBuff, const wchar_t *inBuff, size_t outLen) const size_t wxMBConv::WC2MB(char *outBuff, const wchar_t *inBuff, size_t outLen) const
{ {
const size_t nulLen = GetMBNulLen(); size_t rc = FromWChar(outBuff, outLen, inBuff);
size_t rc = FromWChar(outBuff, outLen + nulLen, inBuff);
if ( rc != wxCONV_FAILED ) if ( rc != wxCONV_FAILED )
{ {
rc -= nulLen; rc -= GetMBNulLen();
} }
return rc; return rc;

View File

@@ -2252,8 +2252,10 @@ void wxMacMLTEControl::SetTXNData( const wxString& st, TXNOffset start, TXNOffse
#else #else
wxMBConvUTF16 converter ; wxMBConvUTF16 converter ;
ByteCount byteBufferLen = converter.WC2MB( NULL, st.wc_str(), 0 ) ; ByteCount byteBufferLen = converter.WC2MB( NULL, st.wc_str(), 0 ) ;
UniChar *unibuf = (UniChar*)malloc( byteBufferLen ) ; wxASSERT_MSG( byteBufferLen != wxCONV_FAILED,
converter.WC2MB( (char*)unibuf, st.wc_str(), byteBufferLen ) ; _T("Conversion to UTF-16 unexpectedly failed") );
UniChar *unibuf = (UniChar*)malloc( byteBufferLen + 2 ) ; // 2 for NUL in UTF-16
converter.WC2MB( (char*)unibuf, st.wc_str(), byteBufferLen + 2 ) ;
TXNSetData( m_txn, kTXNUnicodeTextData, (void*)unibuf, byteBufferLen, start, end ) ; TXNSetData( m_txn, kTXNUnicodeTextData, (void*)unibuf, byteBufferLen, start, end ) ;
free( unibuf ) ; free( unibuf ) ;
#endif #endif

View File

@@ -947,14 +947,14 @@ wxTextCtrl::StreamIn(const wxString& value,
return false; return false;
#if wxUSE_WCHAR_T #if wxUSE_WCHAR_T
wxWCharBuffer wchBuf(len); wxWCharBuffer wchBuf(len); // allocates one extra character
wchar_t *wpc = wchBuf.data(); wchar_t *wpc = wchBuf.data();
#else #else
wchar_t *wchBuf = (wchar_t *)malloc((len + 1)*sizeof(wchar_t)); wchar_t *wchBuf = (wchar_t *)malloc((len + 1)*sizeof(wchar_t));
wchar_t *wpc = wchBuf; wchar_t *wpc = wchBuf;
#endif #endif
conv.MB2WC(wpc, value, value.length()); conv.MB2WC(wpc, value, len + 1);
#endif // wxUSE_UNICODE_MSLU #endif // wxUSE_UNICODE_MSLU
// finally, stream it in the control // finally, stream it in the control

View File

@@ -807,41 +807,48 @@ void MBConvTestCase::BufSize()
CPPUNIT_ASSERT( conv1251.IsOk() ); CPPUNIT_ASSERT( conv1251.IsOk() );
const char *cp1251text = const char *cp1251text =
"\313\301\326\305\324\323\321 \325\304\301\336\316\331\315"; "\313\301\326\305\324\323\321 \325\304\301\336\316\331\315";
const size_t cp1251textLen = strlen(cp1251text);
const size_t lenW = conv1251.MB2WC(NULL, cp1251text, cp1251textLen); const size_t lenW = conv1251.MB2WC(NULL, cp1251text, 0);
CPPUNIT_ASSERT( lenW != wxCONV_FAILED ); CPPUNIT_ASSERT_EQUAL( strlen(cp1251text), lenW );
wxWCharBuffer wbuf(lenW); wxWCharBuffer wbuf(lenW + 1); // allocates lenW + 2 characters
wbuf.data()[lenW + 1] = L'!';
// lenW-1 is not enough // lenW is not enough because it's the length and we need the size
CPPUNIT_ASSERT_EQUAL( CPPUNIT_ASSERT_EQUAL(
wxCONV_FAILED, conv1251.MB2WC(wbuf.data(), cp1251text, lenW - 1) ); wxCONV_FAILED, conv1251.MB2WC(wbuf.data(), cp1251text, lenW) );
// lenW is just fine // lenW+1 is just fine
CPPUNIT_ASSERT(
conv1251.MB2WC(wbuf.data(), cp1251text, lenW) != wxCONV_FAILED );
// of course, greater values work too
CPPUNIT_ASSERT( CPPUNIT_ASSERT(
conv1251.MB2WC(wbuf.data(), cp1251text, lenW + 1) != wxCONV_FAILED ); conv1251.MB2WC(wbuf.data(), cp1251text, lenW + 1) != wxCONV_FAILED );
// of course, greater values work too
CPPUNIT_ASSERT(
conv1251.MB2WC(wbuf.data(), cp1251text, lenW + 2) != wxCONV_FAILED );
// but they shouldn't write more stuff to the buffer
CPPUNIT_ASSERT_EQUAL( L'!', wbuf[lenW + 1] );
// test in the other direction too, using an encoding with multibyte NUL // test in the other direction too, using an encoding with multibyte NUL
wxCSConv convUTF16(_T("UTF-16")); wxCSConv convUTF16(_T("UTF-16LE"));
CPPUNIT_ASSERT( convUTF16.IsOk() ); CPPUNIT_ASSERT( convUTF16.IsOk() );
const wchar_t *utf16text = L"Hello"; const wchar_t *utf16text = L"Hello";
const size_t utf16textLen = wcslen(utf16text);
const size_t lenMB = convUTF16.WC2MB(NULL, utf16text, utf16textLen); const size_t lenMB = convUTF16.WC2MB(NULL, utf16text, 0);
CPPUNIT_ASSERT( lenMB != wxCONV_FAILED ); CPPUNIT_ASSERT_EQUAL( wcslen(utf16text)*2, lenMB );
wxCharBuffer buf(lenMB + 1); // it only adds 1 for NUL on its own, we need 2 wxCharBuffer buf(lenMB + 2); // it only adds 1 for NUL on its own, we need 2
// for NUL and an extra one for the guard byte
buf.data()[lenMB + 2] = '?';
CPPUNIT_ASSERT_EQUAL( CPPUNIT_ASSERT_EQUAL(
wxCONV_FAILED, convUTF16.WC2MB(buf.data(), utf16text, lenMB - 1) ); wxCONV_FAILED, convUTF16.WC2MB(buf.data(), utf16text, lenMB) );
CPPUNIT_ASSERT_EQUAL(
wxCONV_FAILED, convUTF16.WC2MB(buf.data(), utf16text, lenMB + 1) );
CPPUNIT_ASSERT( CPPUNIT_ASSERT(
convUTF16.WC2MB(buf.data(), utf16text, lenMB) != wxCONV_FAILED ); convUTF16.WC2MB(buf.data(), utf16text, lenMB + 2) != wxCONV_FAILED );
CPPUNIT_ASSERT( CPPUNIT_ASSERT(
convUTF16.WC2MB(buf.data(), utf16text, lenMB + 1) != wxCONV_FAILED ); convUTF16.WC2MB(buf.data(), utf16text, lenMB + 3) != wxCONV_FAILED );
CPPUNIT_ASSERT_EQUAL( '?', buf[lenMB + 2] );
} }
WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_iconv( const wxChar* name ); WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_iconv( const wxChar* name );