QStringConverter: widen nameForEncoding()'s contract

Coverity apparently mixes bootstrap and non-bootstrap builds: it
complains that Encoding::Latin1 indexes encodingInterfaces[]
out-of-range (apparently taking the size of the latter from a
bootstrapped and the value of the former from a non-bootstrap build).

That should somehow be fixed in the Coverity configuration, but it
highlighted the fact that we have a narrow-contract function in this
security-critical class that can trivially have a wide contract, so
widen the contract by returning nullptr for invalid Encoding values.

Consequently, mark the function as noexcept.

As a drive-by, mark it also as Q_DECL_PURE_FUNCTION.

[ChangeLog][QtCore][QStringConverter] The nameForEncoding() function
now returns nullptr for an invalid Encoding value. Before, such a call
resulted in undefined behavior.

Pick-to: 6.9 6.8 6.5
Coverity-Id: 480251
Change-Id: Ie1c5c9df6881147a1ff44fe549e50748b2f5b7da
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
This commit is contained in:
Marc Mutz 2025-04-07 21:06:49 +02:00
parent 07255301ea
commit 48959f7e5b
2 changed files with 12 additions and 4 deletions

View File

@ -2710,11 +2710,19 @@ QStringDecoder QStringDecoder::decoderForHtml(QByteArrayView data)
#endif // !QT_BOOTSTRAPPED
/*!
Returns the canonical name for encoding \a e.
Returns the canonical name for encoding \a e or \nullptr if \a e is an
invalid value.
\note In Qt versions prior to 6.10, 6.9.1, 6.8.4 or 6.5.9, calling this
function with an invalid argument resulted in undefined behavior. Since the
above-mentioned Qt versions, it returns nullptr instead.
*/
const char *QStringConverter::nameForEncoding(QStringConverter::Encoding e)
const char *QStringConverter::nameForEncoding(QStringConverter::Encoding e) noexcept
{
return encodingInterfaces[int(e)].name;
auto i = size_t(e);
if (Q_UNLIKELY(i >= std::size(encodingInterfaces)))
return nullptr;
return encodingInterfaces[i].name;
}
/*!

View File

@ -162,7 +162,7 @@ public:
Q_CORE_EXPORT static std::optional<Encoding> encodingForName(const char *name) noexcept;
#endif
Q_CORE_EXPORT static std::optional<Encoding> encodingForName(QAnyStringView name) noexcept;
Q_CORE_EXPORT static const char *nameForEncoding(Encoding e);
Q_DECL_PURE_FUNCTION Q_CORE_EXPORT static const char *nameForEncoding(Encoding e) noexcept;
Q_CORE_EXPORT static std::optional<Encoding>
encodingForData(QByteArrayView data, char16_t expectedFirstCharacter = 0) noexcept;
Q_CORE_EXPORT static std::optional<Encoding> encodingForHtml(QByteArrayView data);