]> git.saurik.com Git - wxWidgets.git/commitdiff
fix off by one bug in the buffer size (fixes #10039)
authorVadim Zeitlin <vadim@wxwidgets.org>
Sun, 12 Oct 2008 14:51:45 +0000 (14:51 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Sun, 12 Oct 2008 14:51:45 +0000 (14:51 +0000)
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@56246 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

src/common/strconv.cpp
tests/mbconv/mbconvtest.cpp

index 31dc602f35926d94fb5b16170627c31441da8991..ae7fa502312f48e87f978f5959ed97f42dac9763 100644 (file)
@@ -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;
index b5d0185467718f2d240988262948671c34f68109..718f87607ed0ed23787327997627cfe7244ba00e 100644 (file)
@@ -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 );