summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Adams <chris.adams@qinetic.com.au>2018-11-21 16:46:07 +1000
committerChristopher Adams <chris.adams@jollamobile.com>2018-11-29 00:59:45 +0000
commit380605ef048372a40587f0231ba00df146bc070e (patch)
treeb628f586ddad43b08b2c19c85e5c350fb35167e9
parentcba196735e9c89d1bbe2230493b43b92f1596c4b (diff)
Improve handling of malformed Versit documents
The previous fix only handled cases where the empty lines were interior to an outer document. This commit adds handling for leading empty lines, and whitespace-only lines within nested documents. Change-Id: If0f99442c315509a0df95279b299150d7339bc07 Reviewed-by: Tempura San <tempura.san@gmail.com> Reviewed-by: Matthew Vogt <matthew.vogt@qinetic.com.au>
-rw-r--r--src/versit/qversitreader_p.cpp9
-rw-r--r--tests/auto/versit/qversitreader/tst_qversitreader.cpp103
2 files changed, 110 insertions, 2 deletions
diff --git a/src/versit/qversitreader_p.cpp b/src/versit/qversitreader_p.cpp
index 7ddf2c601..e13b0892e 100644
--- a/src/versit/qversitreader_p.cpp
+++ b/src/versit/qversitreader_p.cpp
@@ -610,7 +610,12 @@ bool QVersitReaderPrivate::parseVersitDocument(LineReader* lineReader, QVersitDo
QVersitProperty property;
property = parseNextVersitProperty(document->type(), lineReader);
- QString propertyValue = property.value().trimmed().toUpper();
+ while (property.isEmpty() && !lineReader->atEnd()) {
+ // Work around malformed documents by ignoring empty leading lines
+ property = parseNextVersitProperty(document->type(), lineReader);
+ }
+
+ const QString propertyValue = property.value().trimmed().toUpper();
if (property.isEmpty()) {
// A blank document (or end of file) was found.
document->clear();
@@ -689,7 +694,7 @@ QVersitProperty QVersitReaderPrivate::parseNextVersitProperty(
LineReader* lineReader)
{
LByteArray line = lineReader->readLine();
- if (line.isEmpty())
+ if (line.isEmpty() || line.toByteArray().trimmed().isEmpty())
return QVersitProperty();
// Otherwise, do stuff.
diff --git a/tests/auto/versit/qversitreader/tst_qversitreader.cpp b/tests/auto/versit/qversitreader/tst_qversitreader.cpp
index 7d4bdaf43..22a1b8306 100644
--- a/tests/auto/versit/qversitreader/tst_qversitreader.cpp
+++ b/tests/auto/versit/qversitreader/tst_qversitreader.cpp
@@ -416,6 +416,109 @@ void tst_QVersitReader::testReading()
QCOMPARE(mReader->error(), QVersitReader::NoError);
QCOMPARE(results.count(), 1);
+ // Exception case for whitespace-only property values
+ const QByteArray whitespaceLinesTest =
+ "BEGIN:VCARD\r\n"
+ "VERSION:4.0\r\n"
+ "FN:John\r\n"
+ " \r\n"
+ "\t\r\n"
+ "EMAIL;ENCODING=QUOTED-PRINTABLE:john.citizen@example.com\r\n"
+ "END:VCARD\r\n";
+ mInputDevice->close();
+ mInputDevice->setData(whitespaceLinesTest);
+ mInputDevice->open(QBuffer::ReadOnly);
+ mInputDevice->seek(0);
+ QVERIFY2(mReader->startReading(), QString::number(mReader->error()).toLatin1().data());
+ QVERIFY2(mReader->waitForFinished(), QString::number(mReader->error()).toLatin1().data());
+ results = mReader->results();
+ QCOMPARE(mReader->state(), QVersitReader::FinishedState);
+ QCOMPARE(mReader->error(), QVersitReader::NoError);
+ QCOMPARE(results.count(), 1);
+
+ // Exception case for leading whitespace lines
+ const QByteArray leadingWhitespaceTest =
+ "\r\n"
+ " \r\n"
+ "BEGIN:VCARD\r\n"
+ "VERSION:4.0\r\n"
+ "FN:John\r\n"
+ "EMAIL;ENCODING=QUOTED-PRINTABLE:john.citizen@example.com\r\n"
+ "END:VCARD\r\n";
+ mInputDevice->close();
+ mInputDevice->setData(leadingWhitespaceTest);
+ mInputDevice->open(QBuffer::ReadOnly);
+ mInputDevice->seek(0);
+ QVERIFY2(mReader->startReading(), QString::number(mReader->error()).toLatin1().data());
+ QVERIFY2(mReader->waitForFinished(), QString::number(mReader->error()).toLatin1().data());
+ results = mReader->results();
+ QCOMPARE(mReader->state(), QVersitReader::FinishedState);
+ QCOMPARE(mReader->error(), QVersitReader::NoError);
+ QCOMPARE(results.count(), 1);
+
+ // Exception case for leading whitespace lines between nested documents
+ const QByteArray interiorWhitespaceNestedTest =
+ "BEGIN:VCALENDAR\r\n"
+ "VERSION:2.0\r\n"
+ "BEGIN:VEVENT\r\n"
+ "DTSTART:20120101T120000Z\r\n"
+ "DTEND:20120101T130000Z\r\n"
+ "COMMENT:Comment\r\n"
+ "DESCRIPTION:Description\r\n"
+ "SUMMARY:Display label\r\n"
+ "PRIORITY:9\r\n"
+ "CATEGORIES:Tag\r\n"
+ "CREATED:20181121T061003Z\r\n"
+ "LAST-MODIFIED:20181121T061003Z\r\n"
+ "X-QTPROJECT-EXTENDED-DETAIL:extended detail: string data;[\\n \"data\"\\n]\\n\r\n"
+ " \r\n"
+ "X-QTPROJECT-EXTENDED-DETAIL:extended detail: integer data;[\\n 1\\n]\\n\r\n"
+ "X-QTPROJECT-EXTENDED-DETAIL:extended detail: array data;[\\n [\\n \"s\r\n"
+ " tring 1\"\\,\\n \"string 2\"\\n ]\\n]\\n\r\n"
+ "X-QTPROJECT-EXTENDED-DETAIL:extended detail: object data;[\\n {\\n \"\r\n"
+ " key 1\": \"string 1\"\\,\\n \"key 2\": \"string 2\"\\n }\\n]\\n\r\n"
+ "X-QTPROJECT-VERSION:1;1234\r\n"
+ "UID:{024ba6db-703f-4445-ae25-2f600d7503c3}\r\n"
+ "BEGIN:VALARM\r\n"
+ "ACTION:AUDIO\r\n"
+ "TRIGGER;RELATED=START:-PT0S\r\n"
+ "REPEAT:1\r\n"
+ "DURATION:PT1S\r\n"
+ "ATTACH:ftp://audible_reminder_data_url\r\n"
+ "END:VALARM\r\n"
+ "BEGIN:VALARM\r\n"
+ "ACTION:EMAIL\r\n"
+ "TRIGGER;RELATED=START:-PT0S\r\n"
+ "REPEAT:1\r\n"
+ "DURATION:PT1S\r\n"
+ "ATTACH:Attachment 1\r\n"
+ "ATTACH:Attachment 2\r\n"
+ "ATTENDEE:Recipient 1\r\n"
+ "ATTENDEE:Recipient 2\r\n"
+ "DESCRIPTION:Email reminder body\r\n"
+ "SUMMARY:Email reminder subject\r\n"
+ "END:VALARM\r\n"
+ "BEGIN:VALARM\r\n"
+ "ACTION:DISPLAY\r\n"
+ "TRIGGER;RELATED=START:-PT0S\r\n"
+ "REPEAT:1\r\n"
+ "DURATION:PT1S\r\n"
+ "X-QTPROJECT-ATTACH:ftp://visual_reminder_data_url\r\n"
+ "DESCRIPTION:Visual reminder message\r\n"
+ "END:VALARM\r\n"
+ "END:VEVENT\r\n"
+ "END:VCALENDAR\r\n";
+ mInputDevice->close();
+ mInputDevice->setData(interiorWhitespaceNestedTest);
+ mInputDevice->open(QBuffer::ReadOnly);
+ mInputDevice->seek(0);
+ QVERIFY2(mReader->startReading(), QString::number(mReader->error()).toLatin1().data());
+ QVERIFY2(mReader->waitForFinished(), QString::number(mReader->error()).toLatin1().data());
+ results = mReader->results();
+ QCOMPARE(mReader->state(), QVersitReader::FinishedState);
+ QCOMPARE(mReader->error(), QVersitReader::NoError);
+ QCOMPARE(results.count(), 1);
+
// vCard 4.0
const QByteArray& vcard40 =
"BEGIN:VCARD\r\nVERSION:4.0\r\nFN:John\r\nEND:VCARD\r\n";