summaryrefslogtreecommitdiffstats
path: root/src/corelib/json/qjson.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/qjson.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/qjson.cpp')
-rw-r--r--src/corelib/json/qjson.cpp11
1 files changed, 10 insertions, 1 deletions
diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp
index ed6ef74e3c..8215aeefc0 100644
--- a/src/corelib/json/qjson.cpp
+++ b/src/corelib/json/qjson.cpp
@@ -149,6 +149,10 @@ bool Data::valid() const
int Base::reserveSpace(uint dataSize, int posInTable, uint numItems, bool replace)
{
Q_ASSERT(posInTable >= 0 && posInTable <= (int)length);
+ if (size + dataSize >= Value::MaxSize) {
+ qWarning("QJson: Document too large to store in data structure %d %d %d", (uint)size, dataSize, Value::MaxSize);
+ return 0;
+ }
offset off = tableOffset;
// move table to new position
@@ -334,7 +338,7 @@ bool Value::isValid(const Base *b) const
/*!
\internal
*/
-int Value::requiredStorage(const QJsonValue &v, bool *compressed)
+int Value::requiredStorage(QJsonValue &v, bool *compressed)
{
*compressed = false;
switch (v.t) {
@@ -351,6 +355,11 @@ int Value::requiredStorage(const QJsonValue &v, bool *compressed)
}
case QJsonValue::Array:
case QJsonValue::Object:
+ if (v.d && v.d->compactionCounter) {
+ v.detach();
+ v.d->compact();
+ v.base = static_cast<QJsonPrivate::Base *>(v.d->header->root());
+ }
return v.base ? v.base->size : sizeof(QJsonPrivate::Base);
case QJsonValue::Undefined:
case QJsonValue::Null: