From 59e03152a9bbff1c9193d67b7290365ef2c75e47 Mon Sep 17 00:00:00 2001 From: Marc Mutz Date: Mon, 12 Dec 2022 16:11:19 +0100 Subject: [PATCH] QXmlStreamWriter: fix a thinko in doWriteToDevice(QSV) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Check for state.remainingChars to signal an encoding error only after the last chunk has been processed. Splitting surrogates at chunk boundaries is normal operation, not an error. Only if this happens at the end of the whole input should we raise an error. Amends fa2153bd10057d7adbc5f5ededa1fd97c4a68161. Change-Id: Id92e37becaed25bbc11e0c22dedc4d41fb23f92a Reviewed-by: Qt CI Bot Reviewed-by: Fabian Kosmale (cherry picked from commit 4ccb10dc918c3d4d01afa1ad718a24eb5fa49a3c) Reviewed-by: MÃ¥rten Nordheim --- src/corelib/serialization/qxmlstream.cpp | 6 ++---- .../corelib/serialization/qxmlstream/tst_qxmlstream.cpp | 9 ++++++++- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index e68544b1cf5..b32d32c1a41 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -3069,13 +3069,11 @@ void QXmlStreamWriterPrivate::doWriteToDevice(QStringView s) while (!s.isEmpty()) { const qsizetype chunkSize = std::min(s.size(), MaxChunkSize); char *end = QUtf8::convertFromUnicode(buffer, s.first(chunkSize), &state); - if (state.remainingChars > 0) { - hasEncodingError = true; - return; - } doWriteToDevice(QUtf8StringView{buffer, end}); s = s.sliced(chunkSize); } + if (state.remainingChars > 0) + hasEncodingError = true; } void QXmlStreamWriterPrivate::doWriteToDevice(QUtf8StringView s) diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index b91182d3097..a91a9bc752f 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -1695,16 +1695,23 @@ void tst_QXmlStream::readBack() const { QFETCH(const int, plane); + constexpr qsizetype MaxChunkSizeWhenEncoding = 512; // from qxmlstream.cpp QBuffer buffer; + QString text = QString(513, 'a'); // one longer than the internal conversion buffer for (char16_t i = 0; i < (std::numeric_limits::max)(); ++i) { const char32_t c = (plane << 16) + i; + // end chunk in invalid character, split surrogates: + const auto pair = QChar::fromUcs4(c); + text.resize(MaxChunkSizeWhenEncoding + 1 - pair.size()); + text += pair; + QVERIFY(buffer.open(QIODevice::WriteOnly|QIODevice::Truncate)); QXmlStreamWriter writer(&buffer); writer.writeStartDocument(); - writer.writeTextElement("a", c); + writer.writeTextElement("a", text); writer.writeEndDocument(); buffer.close();