summaryrefslogtreecommitdiffstats
path: root/src/corelib/serialization/qxmlstream.cpp
diff options
context:
space:
mode:
authorIvan Solovev <ivan.solovev@qt.io>2025-03-31 16:52:20 +0200
committerIvan Solovev <ivan.solovev@qt.io>2025-04-04 22:04:45 +0200
commitb6b725aef59390f403a1a39f49d1318c48f13c07 (patch)
tree61bdd1c02b22c75e0cc9dc3bc94b2515357d4af3 /src/corelib/serialization/qxmlstream.cpp
parent35dd681f2ba00e7196e59309d76f920ad8807205 (diff)
QXmlStreamReader: fix addData() unnecessary conversion to UTF-8
The addData(QASV) overload was unconditionally converting UTF-16 and Latin1 data to UTF-8. However, if we already started reading the XML document, and we know that its encoding is UTF-16 or Latin1, then we know for sure that the new data has to be added as-is. Amends 6bc227a06a0d1392d220aa79ddb1cdc145d4f76e. [ChangeLog][QtCore][QXmlStreamReader] Fixed a bug when addData(QAnyStringView) was incorrectly recoding UTF-16 and Latin1 data to UTF-8, thus potentially mangling it. Fixes: QTBUG-135129 Pick-to: 6.9 6.8 6.5 Change-Id: Ie1171a5e5596b72a6f160031a4c5a9df3baae4fd Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/serialization/qxmlstream.cpp')
-rw-r--r--src/corelib/serialization/qxmlstream.cpp23
1 files changed, 23 insertions, 0 deletions
diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp
index 58fc076c216..c7527e29634 100644
--- a/src/corelib/serialization/qxmlstream.cpp
+++ b/src/corelib/serialization/qxmlstream.cpp
@@ -551,6 +551,15 @@ QIODevice *QXmlStreamReader::device() const
\sa readNext(), clear()
*/
+static bool isDecoderForEncoding(const QStringDecoder &dec, QStringDecoder::Encoding enc)
+{
+ if (!dec.isValid())
+ return false;
+
+ const QAnyStringView nameView{dec.name()};
+ return !nameView.empty() && nameView == QStringDecoder::nameForEncoding(enc);
+}
+
/*!
Adds more \a data for the reader to read. This function does
nothing if the reader has a device().
@@ -565,11 +574,25 @@ void QXmlStreamReader::addData(QAnyStringView data)
Q_D(QXmlStreamReader);
data.visit([this, d](auto data) {
if constexpr (std::is_same_v<decltype(data), QStringView>) {
+ if (d->lockEncoding && isDecoderForEncoding(d->decoder, QStringDecoder::Utf16)) {
+ // We already expect the data in the proper encoding, no need
+ // to recode the data.
+ addDataImpl(QByteArray{reinterpret_cast<const char *>(data.utf16()),
+ data.size() * 2});
+ return;
+ }
+ // keep the pre-existing behavior
d->lockEncoding = true;
if (!d->decoder.isValid())
d->decoder = QStringDecoder(QStringDecoder::Utf8);
addDataImpl(data.toUtf8());
} else if constexpr (std::is_same_v<decltype(data), QLatin1StringView>) {
+ if (d->lockEncoding && isDecoderForEncoding(d->decoder, QStringDecoder::Latin1)) {
+ // We already expect the data in the proper encoding, no need
+ // to recode the data.
+ addDataImpl(QByteArray{data.data(), data.size()});
+ return;
+ }
// Conversion to a QString is required, to avoid breaking
// pre-existing (before porting to QAnyStringView) behavior.
d->lockEncoding = true;