From 163726cf946bcf519bf17ab747c04363e056041e Mon Sep 17 00:00:00 2001 From: Denis Dzyubenko Date: Wed, 11 Jan 2012 15:13:30 +0100 Subject: Fixed object validation in a boundary case When a latin1 string stored that has only 2 characters or less, the size of the data is 2+2 (2 bytes for the string length and 2 bytes for the content), so it is quite possible that the table is located right after the data. It should be safe to check offset+sizeof(uit) > tableOffset even for shorter strings because values and table is always aligned, hence even for an empty string, it will take 4 bytes. Change-Id: I859ae0be46ebab38feeaa6aa22fbc31f2f95d443 Sanity-Review: Qt Sanity Bot Reviewed-by: Lars Knoll --- src/qjson.cpp | 2 +- tests/auto/test2.json | 1 + tests/auto/tst_qtjson.cpp | 32 ++++++++++++++++++++++++++++++-- 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 tests/auto/test2.json diff --git a/src/qjson.cpp b/src/qjson.cpp index 5936949..41d0144 100644 --- a/src/qjson.cpp +++ b/src/qjson.cpp @@ -270,7 +270,7 @@ bool Value::isValid(const Base *b) const if (!offset) return true; - if (offset + sizeof(uint) >= b->tableOffset) + if (offset + sizeof(uint) > b->tableOffset) return false; int s = usedStorage(b); diff --git a/tests/auto/test2.json b/tests/auto/test2.json new file mode 100644 index 0000000..303f879 --- /dev/null +++ b/tests/auto/test2.json @@ -0,0 +1 @@ +{ "foo": ["ab"] } diff --git a/tests/auto/tst_qtjson.cpp b/tests/auto/tst_qtjson.cpp index 70dfa74..4a749ec 100644 --- a/tests/auto/tst_qtjson.cpp +++ b/tests/auto/tst_qtjson.cpp @@ -89,6 +89,8 @@ private Q_SLOTS: void toJson(); void fromJson(); void fromBinary(); + void toAndFromBinary_data(); + void toAndFromBinary(); void parseNumbers(); void parseStrings(); void testParser(); @@ -469,7 +471,9 @@ void TestQtJson::testObjectNestedEmpty() QJsonDocument(object).toBinaryData(); QVERIFY(object.value("inner").toObject().isEmpty()); QVERIFY(object.value("inner2").toObject().isEmpty()); - QJsonObject reconstituted(QJsonDocument::fromBinaryData(QJsonDocument(object).toBinaryData()).object()); + QJsonDocument doc = QJsonDocument::fromBinaryData(QJsonDocument(object).toBinaryData()); + QVERIFY(doc.isValid()); + QJsonObject reconstituted(doc.object()); QCOMPARE(reconstituted.value("inner").toObject().size(), 0); QCOMPARE(reconstituted.value("inner").type(), QJsonValue::Object); QCOMPARE(reconstituted.value("inner2").type(), QJsonValue::Object); @@ -1013,17 +1017,41 @@ void TestQtJson::fromBinary() QByteArray testJson = file.readAll(); QJsonDocument doc = QJsonDocument::fromJson(testJson); + QJsonDocument outdoc = QJsonDocument::fromBinaryData(doc.toBinaryData()); + QVERIFY(outdoc.isValid()); + QVERIFY(doc == outdoc); QFile bfile(QLatin1String("test.bjson")); bfile.open(QFile::ReadOnly); QByteArray binary = bfile.readAll(); QJsonDocument bdoc = QJsonDocument::fromBinaryData(binary); - + QVERIFY(bdoc.isValid()); QVERIFY(doc.toVariant() == bdoc.toVariant()); QVERIFY(doc == bdoc); } +void TestQtJson::toAndFromBinary_data() +{ + QTest::addColumn("filename"); + QTest::newRow("test.json") << QString::fromLatin1("test.json"); + QTest::newRow("test2.json") << QString::fromLatin1("test2.json"); +} + +void TestQtJson::toAndFromBinary() +{ + QFETCH(QString, filename); + QFile file(filename); + QVERIFY(file.open(QFile::ReadOnly)); + QByteArray data = file.readAll(); + + QJsonDocument doc = QJsonDocument::fromJson(data); + QVERIFY(doc.isValid()); + QJsonDocument outdoc = QJsonDocument::fromBinaryData(doc.toBinaryData()); + QVERIFY(outdoc.isValid()); + QVERIFY(doc == outdoc); +} + void TestQtJson::parseNumbers() { { -- cgit v1.2.3