diff options
31 files changed, 57 insertions, 19 deletions
diff --git a/src/corelib/json/qjson.cpp b/src/corelib/json/qjson.cpp index c3b58e59a5..c6fff068ce 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; } diff --git a/src/corelib/json/qjson_p.h b/src/corelib/json/qjson_p.h index b7de24d165..c5fd38e640 100644 --- a/src/corelib/json/qjson_p.h +++ b/src/corelib/json/qjson_p.h @@ -302,12 +302,19 @@ public: 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(); @@ -376,11 +383,16 @@ public: 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(); @@ -567,7 +579,7 @@ public: } int indexOf(const QString &key, bool *exists); - bool isValid() const; + bool isValid(int maxSize) const; }; @@ -577,7 +589,7 @@ public: inline Value at(int i) const; inline Value &operator [](int i); - bool isValid() const; + bool isValid(int maxSize) const; }; @@ -631,12 +643,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); } @@ -662,6 +674,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; diff --git a/tests/auto/corelib/json/invalidBinaryData/10.bjson b/tests/auto/corelib/json/invalidBinaryData/10.bjson Binary files differnew file mode 100644 index 0000000000..12b29b7aa5 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/10.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/11.bjson b/tests/auto/corelib/json/invalidBinaryData/11.bjson Binary files differnew file mode 100644 index 0000000000..cf2b612111 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/11.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/12.bjson b/tests/auto/corelib/json/invalidBinaryData/12.bjson Binary files differnew file mode 100644 index 0000000000..9c2403350e --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/12.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/13.bjson b/tests/auto/corelib/json/invalidBinaryData/13.bjson Binary files differnew file mode 100644 index 0000000000..db6308b1fd --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/13.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/14.bjson b/tests/auto/corelib/json/invalidBinaryData/14.bjson Binary files differnew file mode 100644 index 0000000000..347da4572c --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/14.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/15.bjson b/tests/auto/corelib/json/invalidBinaryData/15.bjson Binary files differnew file mode 100644 index 0000000000..c6c5558934 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/15.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/16.bjson b/tests/auto/corelib/json/invalidBinaryData/16.bjson Binary files differnew file mode 100644 index 0000000000..ae8b57446d --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/16.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/17.bjson b/tests/auto/corelib/json/invalidBinaryData/17.bjson Binary files differnew file mode 100644 index 0000000000..32f0cc0e23 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/17.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/18.bjson b/tests/auto/corelib/json/invalidBinaryData/18.bjson Binary files differnew file mode 100644 index 0000000000..50c89169eb --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/18.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/19.bjson b/tests/auto/corelib/json/invalidBinaryData/19.bjson Binary files differnew file mode 100644 index 0000000000..b922212f45 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/19.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/20.bjson b/tests/auto/corelib/json/invalidBinaryData/20.bjson Binary files differnew file mode 100644 index 0000000000..c965a0d294 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/20.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/21.bjson b/tests/auto/corelib/json/invalidBinaryData/21.bjson Binary files differnew file mode 100644 index 0000000000..98165ee40c --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/21.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/22.bjson b/tests/auto/corelib/json/invalidBinaryData/22.bjson Binary files differnew file mode 100644 index 0000000000..151f773a81 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/22.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/23.bjson b/tests/auto/corelib/json/invalidBinaryData/23.bjson Binary files differnew file mode 100644 index 0000000000..6eb5269470 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/23.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/24.bjson b/tests/auto/corelib/json/invalidBinaryData/24.bjson Binary files differnew file mode 100644 index 0000000000..c55a2a3e3b --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/24.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/25.bjson b/tests/auto/corelib/json/invalidBinaryData/25.bjson Binary files differnew file mode 100644 index 0000000000..6c619f2ae1 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/25.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/26.bjson b/tests/auto/corelib/json/invalidBinaryData/26.bjson Binary files differnew file mode 100644 index 0000000000..3bf303215a --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/26.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/27.bjson b/tests/auto/corelib/json/invalidBinaryData/27.bjson Binary files differnew file mode 100644 index 0000000000..d2656c2287 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/27.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/28.bjson b/tests/auto/corelib/json/invalidBinaryData/28.bjson Binary files differnew file mode 100644 index 0000000000..6797cf8c40 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/28.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/29.bjson b/tests/auto/corelib/json/invalidBinaryData/29.bjson Binary files differnew file mode 100644 index 0000000000..0645dfc3b2 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/29.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/30.bjson b/tests/auto/corelib/json/invalidBinaryData/30.bjson Binary files differnew file mode 100644 index 0000000000..f77fe1efd0 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/30.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/31.bjson b/tests/auto/corelib/json/invalidBinaryData/31.bjson Binary files differnew file mode 100644 index 0000000000..d9840b6582 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/31.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/32.bjson b/tests/auto/corelib/json/invalidBinaryData/32.bjson Binary files differnew file mode 100644 index 0000000000..1de4cb829f --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/32.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/33.bjson b/tests/auto/corelib/json/invalidBinaryData/33.bjson Binary files differnew file mode 100644 index 0000000000..532a31dc08 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/33.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/34.bjson b/tests/auto/corelib/json/invalidBinaryData/34.bjson Binary files differnew file mode 100644 index 0000000000..f498558eff --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/34.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/35.bjson b/tests/auto/corelib/json/invalidBinaryData/35.bjson Binary files differnew file mode 100644 index 0000000000..8701210755 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/35.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/36.bjson b/tests/auto/corelib/json/invalidBinaryData/36.bjson Binary files differnew file mode 100644 index 0000000000..ef5864e911 --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/36.bjson diff --git a/tests/auto/corelib/json/invalidBinaryData/37.bjson b/tests/auto/corelib/json/invalidBinaryData/37.bjson Binary files differnew file mode 100644 index 0000000000..f4dd4ae12f --- /dev/null +++ b/tests/auto/corelib/json/invalidBinaryData/37.bjson diff --git a/tests/auto/corelib/json/tst_qtjson.cpp b/tests/auto/corelib/json/tst_qtjson.cpp index 1665ff696d..f2f9166711 100644 --- a/tests/auto/corelib/json/tst_qtjson.cpp +++ b/tests/auto/corelib/json/tst_qtjson.cpp @@ -103,6 +103,7 @@ private Q_SLOTS: void fromBinary(); void toAndFromBinary_data(); void toAndFromBinary(); + void invalidBinaryData(); void parseNumbers(); void parseStrings(); void parseDuplicateKeys(); @@ -1779,6 +1780,21 @@ void tst_QtJson::toAndFromBinary() QVERIFY(doc == outdoc); } +void tst_QtJson::invalidBinaryData() +{ + QDir dir(testDataDir + "/invalidBinaryData"); + QFileInfoList files = dir.entryInfoList(); + for (int i = 0; i < files.size(); ++i) { + if (!files.at(i).isFile()) + continue; + QFile file(files.at(i).filePath()); + file.open(QIODevice::ReadOnly); + QByteArray bytes = file.readAll(); + QJsonDocument document = QJsonDocument::fromRawData(bytes.constData(), bytes.size()); + QVERIFY(document.isNull()); + } +} + void tst_QtJson::parseNumbers() { { |