summaryrefslogtreecommitdiffstats
path: root/src/corelib
diff options
context:
space:
mode:
Diffstat (limited to 'src/corelib')
-rw-r--r--src/corelib/json/qjson.cpp25
-rw-r--r--src/corelib/json/qjson_p.h37
-rw-r--r--src/corelib/json/qjsonobject.cpp4
-rw-r--r--src/corelib/kernel/qeventdispatcher_winrt.cpp33
-rw-r--r--src/corelib/xml/qxmlstream.cpp2
5 files changed, 67 insertions, 34 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;
}
diff --git a/src/corelib/kernel/qeventdispatcher_winrt.cpp b/src/corelib/kernel/qeventdispatcher_winrt.cpp
index 2ffcf03eb2..607c523435 100644
--- a/src/corelib/kernel/qeventdispatcher_winrt.cpp
+++ b/src/corelib/kernel/qeventdispatcher_winrt.cpp
@@ -42,6 +42,7 @@
#include <QtCore/QCoreApplication>
#include <QtCore/QThread>
#include <QtCore/QHash>
+#include <QtCore/QMutex>
#include <QtCore/qfunctions_winrt.h>
#include <private/qabstracteventdispatcher_p.h>
#include <private/qcoreapplication_p.h>
@@ -106,6 +107,7 @@ public:
private:
QHash<int, QObject *> timerIdToObject;
QVector<WinRTTimerInfo> timerInfos;
+ mutable QMutex timerInfoLock;
QHash<HANDLE, int> timerHandleToId;
QHash<int, HANDLE> timerIdToHandle;
QHash<int, HANDLE> timerIdToCancelHandle;
@@ -122,6 +124,7 @@ private:
timerIdToObject.insert(id, obj);
const quint64 targetTime = qt_msectime() + interval;
const WinRTTimerInfo info(id, interval, type, obj, targetTime);
+ QMutexLocker locker(&timerInfoLock);
if (id >= timerInfos.size())
timerInfos.resize(id + 1);
timerInfos[id] = info;
@@ -130,6 +133,7 @@ private:
bool removeTimer(int id)
{
+ QMutexLocker locker(&timerInfoLock);
if (id >= timerInfos.size())
return false;
@@ -253,14 +257,18 @@ bool QEventDispatcherWinRT::processEvents(QEventLoop::ProcessEventsFlags flags)
if (timerId == INTERRUPT_HANDLE)
break;
- WinRTTimerInfo &info = d->timerInfos[timerId];
- Q_ASSERT(info.timerId != INVALID_TIMER_ID);
+ {
+ QMutexLocker locker(&d->timerInfoLock);
- QCoreApplication::postEvent(this, new QTimerEvent(timerId));
+ WinRTTimerInfo &info = d->timerInfos[timerId];
+ Q_ASSERT(info.timerId != INVALID_TIMER_ID);
- // Update timer's targetTime
- const quint64 targetTime = qt_msectime() + info.interval;
- info.targetTime = targetTime;
+ QCoreApplication::postEvent(this, new QTimerEvent(timerId));
+
+ // Update timer's targetTime
+ const quint64 targetTime = qt_msectime() + info.interval;
+ info.targetTime = targetTime;
+ }
waitResult = WaitForMultipleObjectsEx(timerHandles.count(), timerHandles.constData(), FALSE, 0, TRUE);
}
emit awake();
@@ -428,6 +436,7 @@ QList<QAbstractEventDispatcher::TimerInfo> QEventDispatcherWinRT::registeredTime
}
Q_D(const QEventDispatcherWinRT);
+ QMutexLocker locker(&d->timerInfoLock);
QList<TimerInfo> timerInfos;
for (const WinRTTimerInfo &info : d->timerInfos) {
if (info.object == object && info.timerId != INVALID_TIMER_ID)
@@ -459,6 +468,7 @@ int QEventDispatcherWinRT::remainingTime(int timerId)
}
Q_D(QEventDispatcherWinRT);
+ QMutexLocker locker(&d->timerInfoLock);
const WinRTTimerInfo timerInfo = d->timerInfos.at(timerId);
if (timerInfo.timerId == INVALID_TIMER_ID) {
#ifndef QT_NO_DEBUG
@@ -507,6 +517,9 @@ bool QEventDispatcherWinRT::event(QEvent *e)
case QEvent::Timer: {
QTimerEvent *timerEvent = static_cast<QTimerEvent *>(e);
const int id = timerEvent->timerId();
+
+ QMutexLocker locker(&d->timerInfoLock);
+
Q_ASSERT(id < d->timerInfos.size());
WinRTTimerInfo &info = d->timerInfos[id];
Q_ASSERT(info.timerId != INVALID_TIMER_ID);
@@ -515,17 +528,17 @@ bool QEventDispatcherWinRT::event(QEvent *e)
break;
info.inEvent = true;
+ locker.unlock();
+
QTimerEvent te(id);
QCoreApplication::sendEvent(d->timerIdToObject.value(id), &te);
+ locker.relock();
+
// The timer might have been removed in the meanwhile
if (id >= d->timerInfos.size())
break;
- info = d->timerInfos[id];
- if (info.timerId == INVALID_TIMER_ID)
- break;
-
if (info.interval == 0 && info.inEvent) {
// post the next zero timer event as long as the timer was not restarted
QCoreApplication::postEvent(this, new QTimerEvent(id));
diff --git a/src/corelib/xml/qxmlstream.cpp b/src/corelib/xml/qxmlstream.cpp
index 83b26d50ab..3c5bdfbfc0 100644
--- a/src/corelib/xml/qxmlstream.cpp
+++ b/src/corelib/xml/qxmlstream.cpp
@@ -886,7 +886,7 @@ inline void QXmlStreamReaderPrivate::reallocateStack()
sym_stack = reinterpret_cast<Value*> (realloc(sym_stack, stack_size * sizeof(Value)));
Q_CHECK_PTR(sym_stack);
state_stack = reinterpret_cast<int*> (realloc(state_stack, stack_size * sizeof(int)));
- Q_CHECK_PTR(sym_stack);
+ Q_CHECK_PTR(state_stack);
}