diff options
author | Lars Knoll <lars.knoll@digia.com> | 2013-02-15 10:44:54 +0100 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-05-09 10:20:21 +0200 |
commit | e1d3687d64a19d27448b3f8247505daa99261ea1 (patch) | |
tree | 3792e67b42c833a4a8765f952d4d3f2a2fb4fa63 /src/corelib/json/qjsonparser.cpp | |
parent | 9cc106d9d7d951fcf30f4b0f8606afa6b50892ec (diff) |
Fix crashes when creating large documents
Compact an object in regular intervals when inserting
data into it, to avoid the object becoming huge.
Compact an object/array before inserting into another
array or object.
Check that the document doesn't get so big it's overflowing
the internal data structures.
Task-number: QTBUG-29288
Change-Id: Id39d80dac1e7d5a11f40819f41b4b336bce16947
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Diffstat (limited to 'src/corelib/json/qjsonparser.cpp')
-rw-r--r-- | src/corelib/json/qjsonparser.cpp | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/corelib/json/qjsonparser.cpp b/src/corelib/json/qjsonparser.cpp index e569cbf435..7989d18901 100644 --- a/src/corelib/json/qjsonparser.cpp +++ b/src/corelib/json/qjsonparser.cpp @@ -76,6 +76,7 @@ QT_BEGIN_NAMESPACE #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") +#define JSONERR_DOC_LARGE QT_TRANSLATE_NOOP("QJsonParseError", "too large document") /*! \class QJsonParseError @@ -105,6 +106,7 @@ QT_BEGIN_NAMESPACE \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 + \value DocumentTooLarge The JSON document is too large for the parser to parse it */ /*! @@ -173,6 +175,9 @@ QString QJsonParseError::errorString() const case DeepNesting: sz = JSONERR_DEEP_NEST; break; + case DocumentTooLarge: + sz = JSONERR_DOC_LARGE; + break; } #ifndef QT_BOOTSTRAPPED return QCoreApplication::translate("QJsonParseError", sz); @@ -579,6 +584,10 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) return false; case Quote: { val->type = QJsonValue::String; + if (current - baseOffset >= Value::MaxSize) { + lastError = QJsonParseError::DocumentTooLarge; + return false; + } val->value = current - baseOffset; bool latin1; if (!parseString(&latin1)) @@ -590,6 +599,10 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) } case BeginArray: val->type = QJsonValue::Array; + if (current - baseOffset >= Value::MaxSize) { + lastError = QJsonParseError::DocumentTooLarge; + return false; + } val->value = current - baseOffset; if (!parseArray()) return false; @@ -598,6 +611,10 @@ bool Parser::parseValue(QJsonPrivate::Value *val, int baseOffset) return true; case BeginObject: val->type = QJsonValue::Object; + if (current - baseOffset >= Value::MaxSize) { + lastError = QJsonParseError::DocumentTooLarge; + return false; + } val->value = current - baseOffset; if (!parseObject()) return false; @@ -707,6 +724,10 @@ bool Parser::parseNumber(QJsonPrivate::Value *val, int baseOffset) int pos = reserveSpace(sizeof(double)); *(quint64 *)(data + pos) = qToLittleEndian(ui); + if (current - baseOffset >= Value::MaxSize) { + lastError = QJsonParseError::DocumentTooLarge; + return false; + } val->value = pos - baseOffset; val->latinOrIntValue = false; |