From 753874333a37e050614ab88f25608842dc2dcf0a Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 17 Oct 2008 11:31:22 +0000 Subject: [PATCH] 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 --- docs/changes.txt | 5 +---- src/common/strconv.cpp | 10 +++------ src/mac/carbon/textctrl.cpp | 6 +++-- src/msw/textctrl.cpp | 4 ++-- tests/mbconv/mbconvtest.cpp | 45 +++++++++++++++++++++---------------- 5 files changed, 36 insertions(+), 34 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 1f1d4ba26e..4ecf826406 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -91,10 +91,6 @@ Major new features in 2.8 release 2.8.10: ------- -All: - -- Fixed off by one bug in wxMBConv::MB2WC/WC2MB() functions. - All (GUI): - Fixed wxHTML's pagebreaks computation in tables (D.J.Stauffer). @@ -110,6 +106,7 @@ All (Unix): 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. - Fixed wxArtProvider::GetSizeHint() to return 16x16 for wxART_FRAME_ICON. diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 43c364e94d..48e293d357 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -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 { - // add 1 to available buffer length because MB2WC() parameter counts the - // number of non-NUL characters while ToWChar() counts everything - size_t rc = ToWChar(outBuff, outLen + 1, inBuff); + size_t rc = ToWChar(outBuff, outLen, inBuff); if ( rc != wxCONV_FAILED ) { // 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 { - const size_t nulLen = GetMBNulLen(); - - size_t rc = FromWChar(outBuff, outLen + nulLen, inBuff); + size_t rc = FromWChar(outBuff, outLen, inBuff); if ( rc != wxCONV_FAILED ) { - rc -= nulLen; + rc -= GetMBNulLen(); } return rc; diff --git a/src/mac/carbon/textctrl.cpp b/src/mac/carbon/textctrl.cpp index cc6e1348cf..57dcbb02ba 100644 --- a/src/mac/carbon/textctrl.cpp +++ b/src/mac/carbon/textctrl.cpp @@ -2252,8 +2252,10 @@ void wxMacMLTEControl::SetTXNData( const wxString& st, TXNOffset start, TXNOffse #else wxMBConvUTF16 converter ; ByteCount byteBufferLen = converter.WC2MB( NULL, st.wc_str(), 0 ) ; - UniChar *unibuf = (UniChar*)malloc( byteBufferLen ) ; - converter.WC2MB( (char*)unibuf, st.wc_str(), byteBufferLen ) ; + wxASSERT_MSG( byteBufferLen != wxCONV_FAILED, + _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 ) ; free( unibuf ) ; #endif diff --git a/src/msw/textctrl.cpp b/src/msw/textctrl.cpp index e7b1e32ef4..7887e186ec 100644 --- a/src/msw/textctrl.cpp +++ b/src/msw/textctrl.cpp @@ -947,14 +947,14 @@ wxTextCtrl::StreamIn(const wxString& value, return false; #if wxUSE_WCHAR_T - wxWCharBuffer wchBuf(len); + wxWCharBuffer wchBuf(len); // allocates one extra character wchar_t *wpc = wchBuf.data(); #else wchar_t *wchBuf = (wchar_t *)malloc((len + 1)*sizeof(wchar_t)); wchar_t *wpc = wchBuf; #endif - conv.MB2WC(wpc, value, value.length()); + conv.MB2WC(wpc, value, len + 1); #endif // wxUSE_UNICODE_MSLU // finally, stream it in the control diff --git a/tests/mbconv/mbconvtest.cpp b/tests/mbconv/mbconvtest.cpp index d6b3cfebf9..51880b4996 100644 --- a/tests/mbconv/mbconvtest.cpp +++ b/tests/mbconv/mbconvtest.cpp @@ -807,41 +807,48 @@ void MBConvTestCase::BufSize() CPPUNIT_ASSERT( conv1251.IsOk() ); const char *cp1251text = "\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); - CPPUNIT_ASSERT( lenW != wxCONV_FAILED ); - wxWCharBuffer wbuf(lenW); + const size_t lenW = conv1251.MB2WC(NULL, cp1251text, 0); + CPPUNIT_ASSERT_EQUAL( strlen(cp1251text), 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( - wxCONV_FAILED, conv1251.MB2WC(wbuf.data(), cp1251text, lenW - 1) ); + wxCONV_FAILED, conv1251.MB2WC(wbuf.data(), cp1251text, lenW) ); - // lenW is just fine - CPPUNIT_ASSERT( - conv1251.MB2WC(wbuf.data(), cp1251text, lenW) != wxCONV_FAILED ); - - // of course, greater values work too + // lenW+1 is just fine CPPUNIT_ASSERT( 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 - wxCSConv convUTF16(_T("UTF-16")); + wxCSConv convUTF16(_T("UTF-16LE")); CPPUNIT_ASSERT( convUTF16.IsOk() ); const wchar_t *utf16text = L"Hello"; - const size_t utf16textLen = wcslen(utf16text); - const size_t lenMB = convUTF16.WC2MB(NULL, utf16text, utf16textLen); - CPPUNIT_ASSERT( lenMB != wxCONV_FAILED ); - wxCharBuffer buf(lenMB + 1); // it only adds 1 for NUL on its own, we need 2 + const size_t lenMB = convUTF16.WC2MB(NULL, utf16text, 0); + CPPUNIT_ASSERT_EQUAL( wcslen(utf16text)*2, lenMB ); + 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( - 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( - convUTF16.WC2MB(buf.data(), utf16text, lenMB) != wxCONV_FAILED ); + convUTF16.WC2MB(buf.data(), utf16text, lenMB + 2) != wxCONV_FAILED ); 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 );