Correctly parse non BMP char refs in the sax parser

Update the auto test accordingly, and at the same time remove
all uses of QTextStream (as they aren't required).

Change-Id: I71b7cf6a6b54ea59507f27d5d2d04cc5ae5885fc
Reviewed-by: Sona Kurazyan <sona.kurazyan@qt.io>
This commit is contained in:
Lars Knoll 2020-04-28 15:35:58 +02:00
parent babcabfbc8
commit a4eea312ed
7 changed files with 27 additions and 29 deletions

View File

@ -7475,7 +7475,12 @@ bool QXmlSimpleReaderPrivate::parseReference()
case DoneD: case DoneD:
tmp = ref().toUInt(&ok, 10); tmp = ref().toUInt(&ok, 10);
if (ok) { if (ok) {
stringAddC(QChar(tmp)); if (tmp > 0xffff) {
stringAddC(QChar::highSurrogate(tmp));
stringAddC(QChar::lowSurrogate(tmp));
} else {
stringAddC(QChar(tmp));
}
} else { } else {
reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE)); reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
return false; return false;
@ -7486,7 +7491,12 @@ bool QXmlSimpleReaderPrivate::parseReference()
case DoneH: case DoneH:
tmp = ref().toUInt(&ok, 16); tmp = ref().toUInt(&ok, 16);
if (ok) { if (ok) {
stringAddC(QChar(tmp)); if (tmp > 0xffff) {
stringAddC(QChar::highSurrogate(tmp));
stringAddC(QChar::lowSurrogate(tmp));
} else {
stringAddC(QChar(tmp));
}
} else { } else {
reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE)); reportParseError(QLatin1String(XMLERR_ERRORPARSINGREFERENCE));
return false; return false;

View File

@ -37,7 +37,6 @@
#include "parser.h" #include "parser.h"
static QTextStream qout(stdout, QIODevice::WriteOnly);
static QTextStream qerr(stderr, QIODevice::WriteOnly); static QTextStream qerr(stderr, QIODevice::WriteOnly);
static void usage() static void usage()
@ -79,19 +78,15 @@ int main(int argc, const char *argv[])
if (out_file_name.isEmpty()) if (out_file_name.isEmpty())
out_file_name = file_name + ".ref"; out_file_name = file_name + ".ref";
QFile _out_file; QFile out_file;
QTextStream _out_stream;
QTextStream *out_stream;
if (out_file_name == "-") { if (out_file_name == "-") {
out_stream = &qout; out_file.open(stdout, QFile::WriteOnly);
} else { } else {
_out_file.setFileName(out_file_name); out_file.setFileName(out_file_name);
if (!_out_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { if (!out_file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
qerr << "Could not open " << out_file_name << ": " << strerror(errno) << Qt::endl; qerr << "Could not open " << out_file_name << ": " << strerror(errno) << Qt::endl;
return 1; return 1;
} }
_out_stream.setDevice(&_out_file);
out_stream = &_out_stream;
} }
Parser parser; Parser parser;
@ -102,9 +97,7 @@ int main(int argc, const char *argv[])
parser.parseFile(&in_file); parser.parseFile(&in_file);
out_stream->setCodec("utf8"); out_file.write(parser.result().toUtf8());
*out_stream << parser.result();
return 0; return 0;
} }

View File

@ -142,11 +142,12 @@ bool ContentHandler::startElement(const QString &namespaceURI,
QString ContentHandler::escapeStr(const QString &s) QString ContentHandler::escapeStr(const QString &s)
{ {
QString result = s; QString result = s;
result.replace(QRegularExpression("\""), "\\\""); result.replace(QChar(0), "\\0");
result.replace(QRegularExpression("\\"), "\\\\"); result.replace("\\", "\\\\");
result.replace(QRegularExpression("\n"), "\\n"); result.replace("\"", "\\\"");
result.replace(QRegularExpression("\r"), "\\r"); result.replace("\n", "\\n");
result.replace(QRegularExpression("\t"), "\\t"); result.replace("\r", "\\r");
result.replace("\t", "\\t");
return result; return result;
} }

View File

@ -311,14 +311,12 @@ void tst_QXmlSimpleReader::testGoodXmlFile()
QVERIFY(file.open(QIODevice::ReadOnly)); QVERIFY(file.open(QIODevice::ReadOnly));
Parser parser; Parser parser;
QEXPECT_FAIL(QFINDTESTDATA("xmldocs/valid/sa/089.xml").toLocal8Bit().constData(), "a form feed character is not accepted in XML", Continue);
QVERIFY(parser.parseFile(&file)); QVERIFY(parser.parseFile(&file));
QFile ref_file(file_name + ".ref"); QFile ref_file(file_name + ".ref");
QVERIFY(ref_file.open(QIODevice::ReadOnly | QIODevice::Text)); QVERIFY(ref_file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream ref_stream(&ref_file); QByteArray data = ref_file.readAll();
ref_stream.setCodec("UTF-8"); QString ref_file_contents = QString::fromUtf8(data.constData(), data.size());
QString ref_file_contents = ref_stream.readAll();
QCOMPARE(parser.result(), ref_file_contents); QCOMPARE(parser.result(), ref_file_contents);
} }
@ -393,9 +391,7 @@ void tst_QXmlSimpleReader::testBadXmlFile()
QFile ref_file(file_name + ".ref"); QFile ref_file(file_name + ".ref");
QVERIFY(ref_file.open(QIODevice::ReadOnly | QIODevice::Text)); QVERIFY(ref_file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream ref_stream(&ref_file); QString ref_file_contents = QString::fromUtf8(ref_file.readAll());
ref_stream.setCodec("UTF-8");
QString ref_file_contents = ref_stream.readAll();
QEXPECT_FAIL(QFINDTESTDATA("xmldocs/not-wf/sa/145.xml").toLocal8Bit().constData(), "Surrogate code point 0xD800 should be rejected", Continue); QEXPECT_FAIL(QFINDTESTDATA("xmldocs/not-wf/sa/145.xml").toLocal8Bit().constData(), "Surrogate code point 0xD800 should be rejected", Continue);
@ -469,9 +465,7 @@ void tst_QXmlSimpleReader::testIncrementalParsing()
QFile ref_file(file_name + ".ref"); QFile ref_file(file_name + ".ref");
QVERIFY(ref_file.open(QIODevice::ReadOnly | QIODevice::Text)); QVERIFY(ref_file.open(QIODevice::ReadOnly | QIODevice::Text));
QTextStream ref_stream(&ref_file); QString ref_file_contents = QString::fromUtf8(ref_file.readAll());
ref_stream.setCodec("UTF-8");
QString ref_file_contents = ref_stream.readAll();
QCOMPARE(parser.result(), ref_file_contents); QCOMPARE(parser.result(), ref_file_contents);
} }