diff options
author | Liang Qi <liang.qi@qt.io> | 2016-11-15 09:51:41 +0100 |
---|---|---|
committer | Liang Qi <liang.qi@qt.io> | 2016-11-15 09:58:16 +0100 |
commit | 9808b53fde1dfc65ad3757cc6720e430c3cc89a2 (patch) | |
tree | a0517ae1e290e7bbdb118c9f01f4e6e5d744998c /src/corelib/json | |
parent | c214379156e4c75dcfe59cf73d69b912f4293303 (diff) | |
parent | 246fe271878dbe586b5f3222a78d67dfecd1ca83 (diff) |
Merge remote-tracking branch 'origin/5.6' into 5.7
Conflicts:
configure
src/plugins/platforms/eglfs/qeglfsintegration.cpp
src/plugins/platforms/linuxfb/qlinuxfbintegration.cpp
Change-Id: Id2da7c775439adb62646d5b741ee7c638042b34b
Diffstat (limited to 'src/corelib/json')
-rw-r--r-- | src/corelib/json/qjson.cpp | 25 | ||||
-rw-r--r-- | src/corelib/json/qjson_p.h | 37 | ||||
-rw-r--r-- | src/corelib/json/qjsonobject.cpp | 4 |
3 files changed, 43 insertions, 23 deletions
diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp index 4b98ef076c..5286c4cc8e 100644 --- a/src/corelib/json/qjson.cpp +++ b/src/corelib/json/qjson.cpp @@ -135,10 +135,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; } @@ -223,9 +225,9 @@ int Object::indexOf(QLatin1String key, bool *exists) const 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; @@ -234,8 +236,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) @@ -249,9 +250,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) { @@ -359,12 +360,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; } diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index 8eeff01b59..b1b03601b2 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -310,12 +310,19 @@ public: explicit String(const char *data) { d = (Data *)data; } struct Data { - qle_int length; + qle_uint length; qle_ushort utf16[1]; }; Data *d; + int byteSize() const { return sizeof(uint) + sizeof(ushort) * d->length; } + bool isValid(int maxSize) const { + // Check byteSize() <= maxSize, avoiding integer overflow + maxSize -= sizeof(uint); + return maxSize >= 0 && uint(d->length) <= maxSize / sizeof(ushort); + } + inline String &operator=(const QString &str) { d->length = str.length(); @@ -384,11 +391,16 @@ public: explicit Latin1String(const char *data) { d = (Data *)data; } struct Data { - qle_short length; + qle_ushort length; char latin1[1]; }; Data *d; + int byteSize() const { return sizeof(ushort) + sizeof(char)*(d->length); } + bool isValid(int maxSize) const { + return byteSize() <= maxSize; + } + inline Latin1String &operator=(const QString &str) { int len = d->length = str.length(); @@ -590,7 +602,7 @@ public: int indexOf(const QString &key, bool *exists) const; int indexOf(QLatin1String key, bool *exists) const; - bool isValid() const; + bool isValid(int maxSize) const; }; @@ -600,7 +612,7 @@ public: inline Value at(int i) const; inline Value &operator [](int i); - bool isValid() const; + bool isValid(int maxSize) const; }; @@ -655,12 +667,12 @@ public: // key // value data follows key - int size() const { + uint size() const { int s = sizeof(Entry); if (value.latinKey) - s += sizeof(ushort) + qFromLittleEndian(*(ushort *) ((const char *)this + sizeof(Entry))); + s += shallowLatin1Key().byteSize(); else - s += sizeof(uint) + sizeof(ushort)*qFromLittleEndian(*(int *) ((const char *)this + sizeof(Entry))); + s += shallowKey().byteSize(); return alignedSize(s); } @@ -686,6 +698,15 @@ public: return shallowKey().toString(); } + bool isValid(int maxSize) const { + if (maxSize < (int)sizeof(Entry)) + return false; + maxSize -= sizeof(Entry); + if (value.latinKey) + return shallowLatin1Key().isValid(maxSize); + return shallowKey().isValid(maxSize); + } + bool operator ==(const QString &key) const; inline bool operator !=(const QString &key) const { return !operator ==(key); } inline bool operator >=(const QString &key) const; @@ -698,8 +719,6 @@ public: bool operator >=(const Entry &other) const; }; -inline bool operator!=(const Entry &lhs, const Entry &rhs) { return !(lhs == rhs); } - inline bool Entry::operator >=(const QString &key) const { if (value.latinKey) diff --git a/src/corelib/json/qjsonobject.cpp b/src/corelib/json/qjsonobject.cpp index fb651f0f24..b5b6f36bc6 100644 --- a/src/corelib/json/qjsonobject.cpp +++ b/src/corelib/json/qjsonobject.cpp @@ -599,8 +599,8 @@ bool QJsonObject::operator==(const QJsonObject &other) const for (uint i = 0; i < o->length; ++i) { QJsonPrivate::Entry *e = o->entryAt(i); - QJsonPrivate::Entry *oe = other.o->entryAt(i); - if (*e != *oe || QJsonValue(d, o, e->value) != QJsonValue(other.d, other.o, oe->value)) + QJsonValue v(d, o, e->value); + if (other.value(e->key()) != v) return false; } |