diff options
author | Ulf Hermann <ulf.hermann@qt.io> | 2017-09-12 17:31:31 +0200 |
---|---|---|
committer | Ulf Hermann <ulf.hermann@qt.io> | 2017-09-13 07:29:00 +0000 |
commit | 3b5b8f1d4ab8092e5dd337b7b4e32d85fda2e0b7 (patch) | |
tree | 0c3d8e427eeeb440e4e20a836f9e1721d72e10a7 /tests | |
parent | 71a2dd955cdc15317c83ad35b4845ef864cba0ef (diff) |
QXmlStreamWriter: Avoid writing invalid characters
Some valid UTF-16 characters cannot be expressed in XML 1.0 and a
QString may contain invalid unicode. In both cases we should not write
the respective data to the output stream, as that generates invalid XML,
which then cannot be read back by QXmlStreamReader. In addition we
should report an error if we encounter them.
The change filters the incorrect strings from the output and introduces
an "encodingError" flag which is reported from hasError().
[ChangeLog][Important Behavior Changes] Characters invalid in XML, such
as 0x0 or 0xfffe, as well as strings containing unmatched UTF-16
surrogates are now suppressed from the output of QXmlStreamWriter and
cause the error flag to be set.
Task-number: QTBUG-63150
Change-Id: Ia29bab768fed9681dd68e8934da2a7e3fcdfc3cd
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp index 79cd17b5b3..16a4200b5d 100644 --- a/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp +++ b/tests/auto/corelib/xml/qxmlstream/tst_qxmlstream.cpp @@ -576,6 +576,7 @@ private slots: void invalidStringCharacters_data() const; void invalidStringCharacters() const; void hasError() const; + void readBack() const; private: static QByteArray readFile(const QString &filename); @@ -1695,5 +1696,50 @@ void tst_QXmlStream::invalidStringCharacters_data() const // } +static bool isValidSingleTextChar(const ushort c) +{ + // Conforms to https://www.w3.org/TR/REC-xml/#NT-Char - except for the high range, which is done + // with surrogates. + // Char ::= #x9 | #xA | #xD | [#x20-#xD7FF] | [#xE000-#xFFFD] | [#x10000-#x10FFFF] + static const QPair<ushort, ushort> validRanges[] = { + QPair<ushort, ushort>(0x9, 0xb), + QPair<ushort, ushort>(0xd, 0xe), + QPair<ushort, ushort>(0x20, 0xd800), + QPair<ushort, ushort>(0xe000, 0xfffe) + }; + + for (const QPair<ushort, ushort> &range : validRanges) { + if (c >= range.first && c < range.second) + return true; + } + return false; +} + +void tst_QXmlStream::readBack() const +{ + for (ushort c = 0; c < std::numeric_limits<ushort>::max(); ++c) { + QBuffer buffer; + + QVERIFY(buffer.open(QIODevice::WriteOnly)); + QXmlStreamWriter writer(&buffer); + writer.writeStartDocument(); + writer.writeTextElement("a", QString(QChar(c))); + writer.writeEndDocument(); + buffer.close(); + + if (writer.hasError()) { + QVERIFY2(!isValidSingleTextChar(c), QByteArray::number(c)); + } else { + QVERIFY2(isValidSingleTextChar(c), QByteArray::number(c)); + QVERIFY(buffer.open(QIODevice::ReadOnly)); + QXmlStreamReader reader(&buffer); + do { + reader.readNext(); + } while (!reader.atEnd()); + QVERIFY2(!reader.hasError(), QByteArray::number(c)); + } + } +} + #include "tst_qxmlstream.moc" // vim: et:ts=4:sw=4:sts=4 |