diff options
author | Chris Adams <chris.adams@qinetic.com.au> | 2018-11-21 16:46:07 +1000 |
---|---|---|
committer | Christopher Adams <chris.adams@jollamobile.com> | 2018-11-29 00:59:45 +0000 |
commit | 380605ef048372a40587f0231ba00df146bc070e (patch) | |
tree | b628f586ddad43b08b2c19c85e5c350fb35167e9 | |
parent | cba196735e9c89d1bbe2230493b43b92f1596c4b (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.cpp | 9 | ||||
-rw-r--r-- | tests/auto/versit/qversitreader/tst_qversitreader.cpp | 103 |
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"; |