X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/d16d0917e40c083349e2a98a405433ade3e6f2c4..9e50ed28d99a07bff5f63c9f7952c3ae6be6cab0:/src/common/strconv.cpp diff --git a/src/common/strconv.cpp b/src/common/strconv.cpp index b74c577e2b..8acfe82ead 100644 --- a/src/common/strconv.cpp +++ b/src/common/strconv.cpp @@ -44,10 +44,6 @@ #define wxHAVE_WIN32_MB2WC #endif -#ifdef __SALFORDC__ - #include -#endif - #ifdef HAVE_ICONV #include #include "wx/thread.h" @@ -391,7 +387,11 @@ wxMBConv::cMB2WC(const char *inBuff, size_t inLen, size_t *outLen) const const size_t dstLen = ToWChar(NULL, 0, inBuff, inLen); if ( dstLen != wxCONV_FAILED ) { - wxWCharBuffer wbuf(dstLen - 1); + // notice that we allocate space for dstLen+1 wide characters here + // because we want the buffer to always be NUL-terminated, even if the + // input isn't (as otherwise the caller has no way to know its length) + wxWCharBuffer wbuf(dstLen); + wbuf.data()[dstLen - 1] = L'\0'; if ( ToWChar(wbuf.data(), dstLen, inBuff, inLen) != wxCONV_FAILED ) { if ( outLen ) @@ -417,16 +417,18 @@ wxMBConv::cWC2MB(const wchar_t *inBuff, size_t inLen, size_t *outLen) const size_t dstLen = FromWChar(NULL, 0, inBuff, inLen); if ( dstLen != wxCONV_FAILED ) { - // special case of empty input: can't allocate 0 size buffer below as - // wxCharBuffer insists on NUL-terminating it - wxCharBuffer buf(dstLen ? dstLen - 1 : 1); + const size_t nulLen = GetMBNulLen(); + + // as above, ensure that the buffer is always NUL-terminated, even if + // the input is not + wxCharBuffer buf(dstLen + nulLen - 1); + memset(buf.data() + dstLen, 0, nulLen); if ( FromWChar(buf.data(), dstLen, inBuff, inLen) != wxCONV_FAILED ) { if ( outLen ) { *outLen = dstLen; - const size_t nulLen = GetMBNulLen(); if ( dstLen >= nulLen && !NotAllNULs(buf.data() + dstLen - nulLen, nulLen) ) { @@ -1979,7 +1981,7 @@ wxMBConv_iconv::wxMBConv_iconv(const char *name) if ( m2w != ICONV_T_INVALID ) { char buf[2], *bufPtr; - wchar_t wbuf[2], *wbufPtr; + wchar_t wbuf[2]; size_t insz, outsz; size_t res; @@ -1988,12 +1990,12 @@ wxMBConv_iconv::wxMBConv_iconv(const char *name) wbuf[0] = 0; insz = 2; outsz = SIZEOF_WCHAR_T * 2; - wbufPtr = wbuf; + char* wbufPtr = (char*)wbuf; bufPtr = buf; res = iconv( m2w, ICONV_CHAR_CAST(&bufPtr), &insz, - (char**)&wbufPtr, &outsz); + &wbufPtr, &outsz); if (ICONV_FAILED(res, insz)) { @@ -2089,16 +2091,16 @@ size_t wxMBConv_iconv::MB2WC(wchar_t *buf, const char *psz, size_t n) const size_t outbuf = n * SIZEOF_WCHAR_T; size_t res, cres; - // VS: Use these instead of psz, buf because iconv() modifies its arguments: - wchar_t *bufPtr = buf; const char *pszPtr = psz; if (buf) { + char* bufPtr = (char*)buf; + // have destination buffer, convert there cres = iconv(m2w, ICONV_CHAR_CAST(&pszPtr), &inbuf, - (char**)&bufPtr, &outbuf); + &bufPtr, &outbuf); res = n - (outbuf / SIZEOF_WCHAR_T); if (ms_wcNeedsSwap) @@ -2121,12 +2123,12 @@ size_t wxMBConv_iconv::MB2WC(wchar_t *buf, const char *psz, size_t n) const do { - bufPtr = tbuf; + char* bufPtr = (char*)tbuf; outbuf = 8 * SIZEOF_WCHAR_T; cres = iconv(m2w, ICONV_CHAR_CAST(&pszPtr), &inbuf, - (char**)&bufPtr, &outbuf ); + &bufPtr, &outbuf ); res += 8 - (outbuf / SIZEOF_WCHAR_T); } @@ -2151,8 +2153,8 @@ size_t wxMBConv_iconv::WC2MB(char *buf, const wchar_t *psz, size_t n) const #endif size_t inlen = wxWcslen(psz); - size_t inbuf = inlen * SIZEOF_WCHAR_T; - size_t outbuf = n; + size_t inbuflen = inlen * SIZEOF_WCHAR_T; + size_t outbuflen = n; size_t res, cres; wchar_t *tmpbuf = 0; @@ -2162,7 +2164,7 @@ size_t wxMBConv_iconv::WC2MB(char *buf, const wchar_t *psz, size_t n) const // need to copy to temp buffer to switch endianness // (doing WC_BSWAP twice on the original buffer won't help, as it // could be in read-only memory, or be accessed in some other thread) - tmpbuf = (wchar_t *)malloc(inbuf + SIZEOF_WCHAR_T); + tmpbuf = (wchar_t *)malloc(inbuflen + SIZEOF_WCHAR_T); for ( size_t i = 0; i < inlen; i++ ) tmpbuf[n] = WC_BSWAP(psz[i]); @@ -2170,12 +2172,13 @@ size_t wxMBConv_iconv::WC2MB(char *buf, const wchar_t *psz, size_t n) const psz = tmpbuf; } + char* inbuf = (char*)psz; if (buf) { // have destination buffer, convert there - cres = iconv( w2m, ICONV_CHAR_CAST(&psz), &inbuf, &buf, &outbuf ); + cres = iconv(w2m, ICONV_CHAR_CAST(&inbuf), &inbuflen, &buf, &outbuflen); - res = n - outbuf; + res = n - outbuflen; // NB: iconv was given only wcslen(psz) characters on input, and so // it couldn't convert the trailing zero. Let's do it ourselves @@ -2192,11 +2195,11 @@ size_t wxMBConv_iconv::WC2MB(char *buf, const wchar_t *psz, size_t n) const do { buf = tbuf; - outbuf = 16; + outbuflen = 16; - cres = iconv( w2m, ICONV_CHAR_CAST(&psz), &inbuf, &buf, &outbuf ); + cres = iconv(w2m, ICONV_CHAR_CAST(&inbuf), &inbuflen, &buf, &outbuflen); - res += 16 - outbuf; + res += 16 - outbuflen; } while ((cres == (size_t)-1) && (errno == E2BIG)); } @@ -2206,7 +2209,7 @@ size_t wxMBConv_iconv::WC2MB(char *buf, const wchar_t *psz, size_t n) const free(tmpbuf); } - if (ICONV_FAILED(cres, inbuf)) + if (ICONV_FAILED(cres, inbuflen)) { wxLogTrace(TRACE_STRCONV, wxT("iconv failed: %s"), wxSysErrorMsg(wxSysErrorCode())); return wxCONV_FAILED; @@ -2451,8 +2454,10 @@ public: return wxCONV_FAILED; } + if ( !n ) + n = wcslen(pwz); wxWCharBuffer wcBuf(n); - if ( MB2WC(wcBuf.data(), buf, n) == wxCONV_FAILED || + if ( MB2WC(wcBuf.data(), buf, n + 1) == wxCONV_FAILED || wcscmp(wcBuf, pwz) != 0 ) { // we didn't obtain the same thing we started from, hence