diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index 4061ebf97b8..c802720dd8f 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -22,6 +22,7 @@ #include "qxmlstream_p.h" #include "qxmlstreamparser_p.h" #include +#include QT_BEGIN_NAMESPACE @@ -2971,9 +2972,12 @@ void QXmlStreamWriterPrivate::writeEscaped(QAnyStringView s, bool escapeWhitespa } }; struct NextUtf16 { - char32_t operator()(const QChar *&it, const QChar *) const + char32_t operator()(const QChar *&it, const QChar *end) const { - return (it++)->unicode(); + QStringIterator decoder(it, end); + char32_t result = decoder.next(u'\0'); + it = decoder.position(); + return result; } }; diff --git a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp index 2ac0f0a9769..e9a6f46d041 100644 --- a/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/serialization/qxmlstream/tst_qxmlstream.cpp @@ -576,6 +576,8 @@ private slots: void writeAttribute() const; void writeBadCharactersUtf8_data() const; void writeBadCharactersUtf8() const; + void writeBadCharactersUtf16_data() const; + void writeBadCharactersUtf16() const; void entitiesAndWhitespace_1() const; void entitiesAndWhitespace_2() const; void testFalsePrematureError() const; @@ -1505,6 +1507,24 @@ void tst_QXmlStream::writeBadCharactersUtf8() const QVERIFY(writer.hasError()); } +void tst_QXmlStream::writeBadCharactersUtf16_data() const +{ + QTest::addColumn("input"); + QTest::addRow("low-surrogate") << u"\xdc00"_s; + QTest::addRow("high-surrogate") << u"\xd800"_s; + QTest::addRow("inverted-surrogate-pair") << u"\xdc00\xd800"_s; + QTest::addRow("high-surrogate+non-surrogate") << u"\xd800z"_s; +} + +void tst_QXmlStream::writeBadCharactersUtf16() const +{ + QFETCH(QString, input); + QString target; + QXmlStreamWriter writer(&target); + writer.writeTextElement("a", input); + QVERIFY(writer.hasError()); +} + void tst_QXmlStream::entitiesAndWhitespace_1() const { QXmlStreamReader reader(QLatin1String("&extEnt;"));