summaryrefslogtreecommitdiffstats
path: root/src/corelib/json/qjson.cpp
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2016-11-02 14:10:47 +0100
committerGiuseppe D'Angelo <giuseppe.dangelo@kdab.com>2016-11-11 12:34:27 +0000
commitbfaa8925d5cc0a59cec3f747a8d982ca819f026b (patch)
treef50e0fde4e197fee070fc2906b16085352b45328 /src/corelib/json/qjson.cpp
parent3c2cb87de2554b9c4f6e2080768fe9ede00aeab3 (diff)
Improve the validation algorithm for binary JSON
Add better boundary checks and catch (hopefully all) cases where invalid binary JSON could cause crashes. Change-Id: I206510b7c5e3ba953802a5f46645878e65704ecc Reviewed-by: Edward Welbourne <edward.welbourne@qt.io>
Diffstat (limited to 'src/corelib/json/qjson.cpp')
-rw-r--r--src/corelib/json/qjson.cpp25
1 files changed, 13 insertions, 12 deletions
diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp
index c3b58e59a50..c6fff068ce1 100644
--- a/src/corelib/json/qjson.cpp
+++ b/src/corelib/json/qjson.cpp
@@ -129,10 +129,12 @@ bool Data::valid() const
return false;
bool res = false;
- if (header->root()->is_object)
- res = static_cast<Object *>(header->root())->isValid();
+ Base *root = header->root();
+ int maxSize = alloc - sizeof(Header);
+ if (root->is_object)
+ res = static_cast<Object *>(root)->isValid(maxSize);
else
- res = static_cast<Array *>(header->root())->isValid();
+ res = static_cast<Array *>(root)->isValid(maxSize);
return res;
}
@@ -195,9 +197,9 @@ int Object::indexOf(const QString &key, bool *exists)
return min;
}
-bool Object::isValid() const
+bool Object::isValid(int maxSize) const
{
- if (tableOffset + length*sizeof(offset) > size)
+ if (size > (uint)maxSize || tableOffset + length*sizeof(offset) > size)
return false;
QString lastKey;
@@ -206,8 +208,7 @@ bool Object::isValid() const
if (entryOffset + sizeof(Entry) >= tableOffset)
return false;
Entry *e = entryAt(i);
- int s = e->size();
- if (table()[i] + s > tableOffset)
+ if (!e->isValid(tableOffset - table()[i]))
return false;
QString key = e->key();
if (key < lastKey)
@@ -221,9 +222,9 @@ bool Object::isValid() const
-bool Array::isValid() const
+bool Array::isValid(int maxSize) const
{
- if (tableOffset + length*sizeof(offset) > size)
+ if (size > (uint)maxSize || tableOffset + length*sizeof(offset) > size)
return false;
for (uint i = 0; i < length; ++i) {
@@ -323,12 +324,12 @@ bool Value::isValid(const Base *b) const
int s = usedStorage(b);
if (!s)
return true;
- if (s < 0 || offset + s > (int)b->tableOffset)
+ if (s < 0 || s > (int)b->tableOffset - offset)
return false;
if (type == QJsonValue::Array)
- return static_cast<Array *>(base(b))->isValid();
+ return static_cast<Array *>(base(b))->isValid(s);
if (type == QJsonValue::Object)
- return static_cast<Object *>(base(b))->isValid();
+ return static_cast<Object *>(base(b))->isValid(s);
return true;
}