Don't rely on wxMBConv::cWC2MB(NULL) returning the exact byte count

UTF-32 conversions use a useful optimization by avoiding the extra scan of the
input wchar_t string in their FromWChar() and cWC2MB() implementation when
they are only asked to compute the required buffer size without actually doing
the conversion. However this means that for an input string containing UTF-16
surrogates (which is possible under MSW where wchar_t is 16 bits) the actual
size of the output string can be smaller than that returned by FromWChar(NULL).

Document that this may happen and avoid relying on the exact equality in the
tests.

See #17070.
This commit is contained in:
Vadim Zeitlin 2015-11-13 19:08:27 +01:00
parent 823a2337f6
commit 37dd89a0da
2 changed files with 12 additions and 6 deletions

View File

@ -121,7 +121,7 @@ public:
including the terminating @c NUL character(s). including the terminating @c NUL character(s).
@return @return
The number of character written (or which would have been written The number of characters written (or which would have been written
if it were non-@NULL) to @a dst or @c wxCONV_FAILED on error. if it were non-@NULL) to @a dst or @c wxCONV_FAILED on error.
*/ */
virtual size_t ToWChar(wchar_t* dst, size_t dstLen, const char* src, virtual size_t ToWChar(wchar_t* dst, size_t dstLen, const char* src,
@ -148,8 +148,13 @@ public:
including the terminating @c NUL character. including the terminating @c NUL character.
@return @return
The number of character written (or which would have been written If @dst is non-@NULL, the number of characters actually written to
if it were non-@NULL) to @a dst or @c wxCONV_FAILED on error. it. If @dst is @NULL, the returned value is at least equal to the
number of characters that would have been written out if it were
non-@NULL, but can be larger than it under the platforms using
UTF-16 as @c wchar_t encoding (this allows a useful optimization in
the implementation of this function for UTF-32). In any case,
@c wxCONV_FAILED is returned on conversion error.
*/ */
virtual size_t FromWChar(char* dst, size_t dstLen, const wchar_t* src, virtual size_t FromWChar(char* dst, size_t dstLen, const wchar_t* src,
size_t srcLen = wxNO_LEN) const; size_t srcLen = wxNO_LEN) const;

View File

@ -1096,15 +1096,16 @@ void MBConvTestCase::TestEncoder(
memcpy( inputCopy.data(), wideBuffer, (wideChars*sizeof(wchar_t)) ); memcpy( inputCopy.data(), wideBuffer, (wideChars*sizeof(wchar_t)) );
inputCopy.data()[wideChars] = 0; inputCopy.data()[wideChars] = 0;
// calculate the output size // calculate the output size: notice that it can be greater than the real
// size as the converter is allowed to estimate the maximal size needed
// instead of computing it precisely
size_t outputWritten = converter.WC2MB size_t outputWritten = converter.WC2MB
( (
0, 0,
(const wchar_t*)inputCopy.data(), (const wchar_t*)inputCopy.data(),
0 0
); );
// make sure the correct output length was calculated CPPUNIT_ASSERT( outputWritten >= multiBytes );
CPPUNIT_ASSERT_EQUAL( multiBytes, outputWritten );
// convert the string // convert the string
size_t guardBytes = 8; // to make sure we're not overrunning the output buffer size_t guardBytes = 8; // to make sure we're not overrunning the output buffer