summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/corelib/json/qjsondocument.h3
-rw-r--r--src/corelib/json/qjsonparser.cpp45
-rw-r--r--src/corelib/json/qjsonparser_p.h3
3 files changed, 47 insertions, 4 deletions
diff --git a/src/corelib/json/qjsondocument.h b/src/corelib/json/qjsondocument.h
index c67899192c..bdb171c3cb 100644
--- a/src/corelib/json/qjsondocument.h
+++ b/src/corelib/json/qjsondocument.h
@@ -68,7 +68,8 @@ struct Q_CORE_EXPORT QJsonParseError
IllegalEscapeSequence,
IllegalUTF8String,
UnterminatedString,
- MissingObject
+ MissingObject,
+ DeepNesting
};
QString errorString() const;
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp
index 6706f12b24..5372bc0a7a 100644
--- a/src/corelib/json/qjsonparser.cpp
+++ b/src/corelib/json/qjsonparser.cpp
@@ -58,6 +58,8 @@ static int indent = 0;
#define DEBUG if (1) ; else qDebug()
#endif
+static const int nestingLimit = 1024;
+
QT_BEGIN_NAMESPACE
// error strings for the JSON parser
@@ -73,6 +75,7 @@ QT_BEGIN_NAMESPACE
#define JSONERR_STR_UTF8 QT_TRANSLATE_NOOP("QJsonParseError", "invalid UTF8 string")
#define JSONERR_UTERM_STR QT_TRANSLATE_NOOP("QJsonParseError", "unterminated string")
#define JSONERR_MISS_OBJ QT_TRANSLATE_NOOP("QJsonParseError", "object is missing after a comma")
+#define JSONERR_DEEP_NEST QT_TRANSLATE_NOOP("QJsonParseError", "too deeply nested document")
/*!
\class QJsonParseError
@@ -84,6 +87,26 @@ QT_BEGIN_NAMESPACE
*/
/*!
+ \enum QJsonParseError::ParseError
+
+ This enum describes the type of error that occurred during the parsing of a JSON document.
+
+ \value NoError No error occured
+ \value UnterminatedObject An object is not correctly terminated with a closing curly bracket
+ \value MissingNameSeparator A comma separating different items is missing
+ \value UnterminatedArray The array is not correctly terminated with a closing square bracket
+ \value MissingValueSeparator A colon separating keys from values inside objects is missing
+ \value IllegalValue The value is illegal
+ \value TerminationByNumber The input stream ended while parsing a number
+ \value IllegalNumber The number is not well formed
+ \value IllegalEscapeSequence An illegal escape sequence occurred in the input
+ \value IllegalUTF8String An illegal UTF8 sequence occurred in the input
+ \value UnterminatedString A string wasn't terminated with a quote
+ \value MissingObject An object was expected but couldn't be found
+ \value DeepNesting The JSON document is too deeply nested for the parser to parse it
+*/
+
+/*!
Returns the human-readable message appropriate to the reported JSON parsing error.
*/
QString QJsonParseError::errorString() const
@@ -126,6 +149,9 @@ QString QJsonParseError::errorString() const
case MissingObject:
sz = JSONERR_MISS_OBJ;
break;
+ case DeepNesting:
+ sz = JSONERR_DEEP_NEST;
+ break;
}
#ifndef QT_BOOTSTRAPPED
return QCoreApplication::translate("QJsonParseError", sz);
@@ -137,7 +163,7 @@ QString QJsonParseError::errorString() const
using namespace QJsonPrivate;
Parser::Parser(const char *json, int length)
- : head(json), json(json), data(0), dataLength(0), current(0), lastError(QJsonParseError::NoError)
+ : head(json), json(json), data(0), dataLength(0), current(0), nestingLevel(0), lastError(QJsonParseError::NoError)
{
end = json + length;
}
@@ -318,6 +344,11 @@ void Parser::ParsedObject::insert(uint offset) {
bool Parser::parseObject()
{
+ if (++nestingLevel > nestingLimit) {
+ lastError = QJsonParseError::DeepNesting;
+ return false;
+ }
+
int objectOffset = reserveSpace(sizeof(QJsonPrivate::Object));
BEGIN << "parseObject pos=" << objectOffset << current << json;
@@ -369,6 +400,8 @@ bool Parser::parseObject()
DEBUG << "current=" << current;
END;
+
+ --nestingLevel;
return true;
}
@@ -407,9 +440,15 @@ bool Parser::parseMember(int baseOffset)
bool Parser::parseArray()
{
BEGIN << "parseArray";
+
+ if (++nestingLevel > nestingLimit) {
+ lastError = QJsonParseError::DeepNesting;
+ return false;
+ }
+
int arrayOffset = reserveSpace(sizeof(QJsonPrivate::Array));
- QVarLengthArray<QJsonPrivate::Value> values;
+ QVarLengthArray<QJsonPrivate::Value, 64> values;
if (!eatSpace()) {
lastError = QJsonParseError::UnterminatedArray;
@@ -453,6 +492,8 @@ bool Parser::parseArray()
DEBUG << "current=" << current;
END;
+
+ --nestingLevel;
return true;
}
diff --git a/src/corelib/json/qjsonparser_p.h b/src/corelib/json/qjsonparser_p.h
index 8085edb2e0..2025f43e38 100644
--- a/src/corelib/json/qjsonparser_p.h
+++ b/src/corelib/json/qjsonparser_p.h
@@ -75,7 +75,7 @@ public:
Parser *parser;
int objectPosition;
- QVarLengthArray<uint> offsets;
+ QVarLengthArray<uint, 64> offsets;
inline QJsonPrivate::Entry *entryAt(int i) const {
return reinterpret_cast<QJsonPrivate::Entry *>(parser->data + objectPosition + offsets[i]);
@@ -101,6 +101,7 @@ private:
char *data;
int dataLength;
int current;
+ int nestingLevel;
QJsonParseError::ParseError lastError;
inline int reserveSpace(int space) {