Improve error offset in JSON parsing
Do not consume white-space after a token before the token has been parsed, otherwise we end up with misleading offsets. This also fixes a wrong error of illegal number in several cases. Change-Id: I492ca4de0346a1d0ab73b1c23d7a72dba812664c Reviewed-by: Lars Knoll <lars.knoll@qt.io> Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@qt.io>
This commit is contained in:
parent
71d21ed500
commit
e133f0cca4
@ -283,7 +283,6 @@ char Parser::nextToken()
|
||||
case ValueSeparator:
|
||||
case EndArray:
|
||||
case EndObject:
|
||||
eatSpace();
|
||||
case Quote:
|
||||
break;
|
||||
default:
|
||||
@ -469,6 +468,10 @@ bool Parser::parseMember(int baseOffset)
|
||||
lastError = QJsonParseError::MissingNameSeparator;
|
||||
return false;
|
||||
}
|
||||
if (!eatSpace()) {
|
||||
lastError = QJsonParseError::UnterminatedObject;
|
||||
return false;
|
||||
}
|
||||
QJsonPrivate::Value val;
|
||||
if (!parseValue(&val, baseOffset))
|
||||
return false;
|
||||
@ -544,6 +547,10 @@ bool Parser::parseArray()
|
||||
nextToken();
|
||||
} else {
|
||||
while (1) {
|
||||
if (!eatSpace()) {
|
||||
lastError = QJsonParseError::UnterminatedArray;
|
||||
return false;
|
||||
}
|
||||
QJsonPrivate::Value val;
|
||||
if (!parseValue(&val, arrayOffset))
|
||||
return false;
|
||||
@ -686,6 +693,12 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset)
|
||||
DEBUG << "value: object";
|
||||
END;
|
||||
return true;
|
||||
case ValueSeparator:
|
||||
// Essentially missing value, but after a colon, not after a comma
|
||||
// like the other MissingObject errors.
|
||||
lastError = QJsonParseError::IllegalValue;
|
||||
return false;
|
||||
case EndObject:
|
||||
case EndArray:
|
||||
lastError = QJsonParseError::MissingObject;
|
||||
return false;
|
||||
|
@ -139,6 +139,9 @@ private Q_SLOTS:
|
||||
void removeNonLatinKey();
|
||||
void documentFromVariant();
|
||||
|
||||
void parseErrorOffset_data();
|
||||
void parseErrorOffset();
|
||||
|
||||
private:
|
||||
QString testDataDir;
|
||||
};
|
||||
@ -2830,5 +2833,35 @@ void tst_QtJson::documentFromVariant()
|
||||
QCOMPARE(do1.object(), do2.object());
|
||||
}
|
||||
|
||||
void tst_QtJson::parseErrorOffset_data()
|
||||
{
|
||||
QTest::addColumn<QByteArray>("json");
|
||||
QTest::addColumn<int>("errorOffset");
|
||||
|
||||
QTest::newRow("Trailing comma in object") << QByteArray("{ \"value\": false, }") << 19;
|
||||
QTest::newRow("Trailing comma in object plus whitespace") << QByteArray("{ \"value\": false, } ") << 19;
|
||||
QTest::newRow("Trailing comma in array") << QByteArray("[ false, ]") << 10;
|
||||
QTest::newRow("Trailing comma in array plus whitespace") << QByteArray("[ false, ] ") << 10;
|
||||
QTest::newRow("Missing value in object") << QByteArray("{ \"value\": , } ") << 12;
|
||||
QTest::newRow("Missing value in array") << QByteArray("[ \"value\" , , ] ") << 13;
|
||||
QTest::newRow("Leading comma in object") << QByteArray("{ , \"value\": false}") << 3;
|
||||
QTest::newRow("Leading comma in array") << QByteArray("[ , false]") << 3;
|
||||
QTest::newRow("Stray ,") << QByteArray(" , ") << 3;
|
||||
QTest::newRow("Stray [") << QByteArray(" [ ") << 5;
|
||||
QTest::newRow("Stray }") << QByteArray(" } ") << 3;
|
||||
}
|
||||
|
||||
void tst_QtJson::parseErrorOffset()
|
||||
{
|
||||
QFETCH(QByteArray, json);
|
||||
QFETCH(int, errorOffset);
|
||||
|
||||
QJsonParseError error;
|
||||
QJsonDocument::fromJson(json, &error);
|
||||
|
||||
QVERIFY(error.error != QJsonParseError::NoError);
|
||||
QCOMPARE(error.offset, errorOffset);
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QtJson)
|
||||
#include "tst_qtjson.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user