From cfda487726eb29b95853c42c54c9a6f97264a4fb Mon Sep 17 00:00:00 2001 From: Ivan Solovev Date: Fri, 21 Mar 2025 11:55:38 +0100 Subject: [PATCH] QXmlStreamReader::addData: lock encoding for QLatin1 case This fixes a bug when addData() is used to add a full Latin1-encoded XML document with a proper "encoding" attribute. Once addData() is called, it immediately converts the data to UTF-8. However, if the encoding is not locked, the parser will later see the "encoding" attribute, and try to interpret the data according to the specified encoding. The QXSR(QASV) constructor is not affected, because it already locks the encoding. Add a unit-test for the issue. Amends 6bc227a06a0d1392d220aa79ddb1cdc145d4f76e. [ChangeLog][QtCore][QXmlStreamReader] Fixed a bug when calling addData() with a Latin1-encoded string containing a full XML document with an encoding attribute, could result in incorrect parsing of this document. Fixes: QTBUG-135033 Pick-to: 6.8 6.5 Change-Id: I9a35d16d743050ea4feccab3d1336747ce0abff4 Reviewed-by: Marc Mutz (cherry picked from commit 4b8659ebf689b79ac88f5935ad662a604f0c8bea) Reviewed-by: Qt Cherry-pick Bot --- src/corelib/serialization/qxmlstream.cpp | 1 + .../qxmlstream/tst_qxmlstream.cpp | 20 +++++++++++++++++++ 2 files changed, 21 insertions(+) diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index 50f87900161..182f3d7e1e8 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -572,6 +572,7 @@ void QXmlStreamReader::addData(QAnyStringView data) } else if constexpr (std::is_same_v) { // Conversion to a QString is required, to avoid breaking // pre-existing (before porting to QAnyStringView) behavior. + d->lockEncoding = true; if (!d->decoder.isValid()) d->decoder = QStringDecoder(QStringDecoder::Utf8); addDataImpl(QString::fromLatin1(data).toUtf8()); diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index d40cb8fa8d0..d0821781222 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -568,6 +568,7 @@ private slots: void readFromQBuffer() const; void readFromQBufferInvalid() const; void readFromLatin1String() const; + void readLatin1Document() const; void readNextStartElement() const; void readElementText() const; void readElementText_data() const; @@ -1229,6 +1230,25 @@ void tst_QXmlStream::readFromLatin1String() const } } +void tst_QXmlStream::readLatin1Document() const +{ + const auto in = "M\xE5rten"_L1; + { + QXmlStreamReader reader(in); + QVERIFY(reader.readNextStartElement()); + QString text = reader.readElementText(); + QCOMPARE(text, "M\xE5rten"_L1); + } + // Same as above, but with addData(), QTBUG-135033 + { + QXmlStreamReader reader; + reader.addData(in); + QVERIFY(reader.readNextStartElement()); + QString text = reader.readElementText(); + QCOMPARE(text, "M\xE5rten"_L1); + } +} + void tst_QXmlStream::readNextStartElement() const { QLatin1String in("text");