From: Vadim Zeitlin Date: Sun, 12 Oct 2008 14:51:45 +0000 (+0000) Subject: fix off by one bug in the buffer size (fixes #10039) X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/8a493b67ac549ba1ffdfcbc4ed68c99917fe8fef?ds=inline fix off by one bug in the buffer size (fixes #10039) git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56246 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index 31dc602f35..ae7fa50231 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -355,7 +355,9 @@ wxMBConv::FromWChar(char *dst, size_t dstLen, size_t wxMBConv::MB2WC(wchar_t *outBuff, const char *inBuff, size_t outLen) const { - size_t rc = ToWChar(outBuff, outLen, inBuff); + // 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); if ( rc != wxCONV_FAILED ) { // ToWChar() returns the buffer length, i.e. including the trailing @@ -368,10 +370,12 @@ 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 rc = FromWChar(outBuff, outLen, inBuff); + const size_t nulLen = GetMBNulLen(); + + size_t rc = FromWChar(outBuff, outLen + nulLen, inBuff); if ( rc != wxCONV_FAILED ) { - rc -= GetMBNulLen(); + rc -= nulLen; } return rc; diff --git a/tests/mbconv/mbconvtest.cpp b/tests/mbconv/mbconvtest.cpp index b5d0185467..718f87607e 100644 --- a/tests/mbconv/mbconvtest.cpp +++ b/tests/mbconv/mbconvtest.cpp @@ -80,6 +80,7 @@ private: CPPUNIT_TEST( IconvTests ); CPPUNIT_TEST( Latin1Tests ); CPPUNIT_TEST( FontmapTests ); + CPPUNIT_TEST( BufSize ); #ifdef HAVE_WCHAR_H CPPUNIT_TEST( UTF8_41 ); CPPUNIT_TEST( UTF8_7f ); @@ -113,6 +114,7 @@ private: void CP1252Tests(); void LibcTests(); void FontmapTests(); + void BufSize(); void IconvTests(); void Latin1Tests(); @@ -807,6 +809,49 @@ void MBConvTestCase::FontmapTests() #endif } +void MBConvTestCase::BufSize() +{ + wxCSConv conv1251(_T("CP1251")); + 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); + + // lenW-1 is not enough + CPPUNIT_ASSERT_EQUAL( + wxCONV_FAILED, conv1251.MB2WC(wbuf.data(), cp1251text, lenW - 1) ); + + // lenW is just fine + CPPUNIT_ASSERT( + conv1251.MB2WC(wbuf.data(), cp1251text, lenW) != wxCONV_FAILED ); + + // of course, greater values work too + CPPUNIT_ASSERT( + conv1251.MB2WC(wbuf.data(), cp1251text, lenW + 1) != wxCONV_FAILED ); + + + // test in the other direction too, using an encoding with multibyte NUL + wxCSConv convUTF16(_T("UTF-16")); + 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 + + CPPUNIT_ASSERT_EQUAL( + wxCONV_FAILED, convUTF16.WC2MB(buf.data(), utf16text, lenMB - 1) ); + CPPUNIT_ASSERT( + convUTF16.WC2MB(buf.data(), utf16text, lenMB) != wxCONV_FAILED ); + CPPUNIT_ASSERT( + convUTF16.WC2MB(buf.data(), utf16text, lenMB + 1) != wxCONV_FAILED ); +} + WXDLLIMPEXP_BASE wxMBConv* new_wxMBConv_iconv( const char* name );