QTextCodec: fix silent truncation of input data to int
The QTextCodec APIs did not account for the fact that QStringView,
QString, and QByteArray uses qsizetype, not int, to represent its
size.
As a result, the size is silently truncated when passing to the
underlying API, which can produce negative values for inputs
larger than INT_MAX. This can lead to all sorts of surprising
results, depending on the codec implementation.
Fix by explicitly checking the input size against INT_MAX. Raise
a warning and return early if the size is greater than this value.
The toUnicode(const char *) overload is special. It is using qstrlen()
to calculate the input size.
The qstrlen() method returns size_t (or uint in 5.15), which is then
truncated to int, and we get the same problem.
Since qstrlen() in 5.15 is broken (returning uint instead of size_t),
fix by using strlen() directly and comparing the result against
INT_MAX. Raise a warning and return early if the size is greater than
this value.
We could theoretically rewrite the code to do the conversion in a loop,
but since it is a compatibility code, the valid usecases are supposed
to use is with inputs less than INT_MAX anyway. If it is required to
deal with a larger input, the chunking can be implemented at the user
side.
[ChangeLog][QTextCodec] Fixed a bug in toUnicode(), fromUnicode(),
and canEncode() methods that could silently truncate the size of
input data if it exceeded INT_MAX. The updated code now raises a
warning and returns an empty QString/QByteArray immediately. To
process long inputs, implement chunking of the input data on the
client side, using the toUnicode() and fromUnicode() overloads that
take the ConverterState as the last parameter.
Task-number: QTBUG-149424
Pick-to: 6.12 6.11 6.8 6.5 5.15
Change-Id: I25f16013ca35685ffb028a3bfbaa325b5b828f64
Reviewed-by: Marc Mutz <marc.mutz@qt.io>