summaryrefslogtreecommitdiffstats
path: root/src/corelib/json/qjsonparser.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@digia.com>2013-02-15 10:44:54 +0100
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-05-09 10:20:21 +0200
commite1d3687d64a19d27448b3f8247505daa99261ea1 (patch)
tree3792e67b42c833a4a8765f952d4d3f2a2fb4fa63 /src/corelib/json/qjsonparser.cpp
parent9cc106d9d7d951fcf30f4b0f8606afa6b50892ec (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.cpp21
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;