QXmlStreamWriter: fix a thinko in doWriteToDevice(QSV)

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 fa2153bd10.

Pick-to: 6.5
Change-Id: Id92e37becaed25bbc11e0c22dedc4d41fb23f92a
Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Reviewed-by: Fabian Kosmale <fabian.kosmale@qt.io>
bb10
Marc Mutz 2022-12-12 16:11:19 +01:00
parent 26c190f57e
commit 4ccb10dc91
2 changed files with 10 additions and 5 deletions

View File

@ -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)

View File

@ -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<char16_t>::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();