diff options
Diffstat (limited to 'src/corelib')
-rw-r--r-- | src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp | 11 | ||||
-rw-r--r-- | src/corelib/itemmodels/qconcatenatetablesproxymodel.h | 1 | ||||
-rw-r--r-- | src/corelib/kernel/qobjectdefs_impl.h | 4 | ||||
-rw-r--r-- | src/corelib/mimetypes/qmimeprovider_p.h | 2 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream.cpp | 36 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream.g | 14 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream.h | 2 | ||||
-rw-r--r-- | src/corelib/serialization/qxmlstream_p.h | 14 | ||||
-rw-r--r-- | src/corelib/thread/qrunnable.cpp | 12 | ||||
-rw-r--r-- | src/corelib/thread/qrunnable.h | 2 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool.cpp | 20 | ||||
-rw-r--r-- | src/corelib/thread/qthreadpool.h | 4 | ||||
-rw-r--r-- | src/corelib/time/qdatetimeparser.cpp | 8 | ||||
-rw-r--r-- | src/corelib/tools/qhash.h | 52 |
14 files changed, 134 insertions, 48 deletions
diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp index 3afa132483..a2597faa93 100644 --- a/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp +++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.cpp @@ -448,6 +448,17 @@ QSize QConcatenateTablesProxyModel::span(const QModelIndex &index) const } /*! + Returns a list of models that were added as source models for this proxy model. + + \since 5.15 +*/ +QList<QAbstractItemModel *> QConcatenateTablesProxyModel::sourceModels() const +{ + Q_D(const QConcatenateTablesProxyModel); + return d->m_models.toList(); +} + +/*! Adds a source model \a sourceModel, below all previously added source models. The ownership of \a sourceModel is not affected by this. diff --git a/src/corelib/itemmodels/qconcatenatetablesproxymodel.h b/src/corelib/itemmodels/qconcatenatetablesproxymodel.h index 69b3a2ba09..1fa84d5f51 100644 --- a/src/corelib/itemmodels/qconcatenatetablesproxymodel.h +++ b/src/corelib/itemmodels/qconcatenatetablesproxymodel.h @@ -56,6 +56,7 @@ public: explicit QConcatenateTablesProxyModel(QObject *parent = nullptr); ~QConcatenateTablesProxyModel(); + QList<QAbstractItemModel *> sourceModels() const; Q_SCRIPTABLE void addSourceModel(QAbstractItemModel *sourceModel); Q_SCRIPTABLE void removeSourceModel(QAbstractItemModel *sourceModel); diff --git a/src/corelib/kernel/qobjectdefs_impl.h b/src/corelib/kernel/qobjectdefs_impl.h index 31ecc8b20d..aed50d6c5a 100644 --- a/src/corelib/kernel/qobjectdefs_impl.h +++ b/src/corelib/kernel/qobjectdefs_impl.h @@ -285,11 +285,15 @@ namespace QtPrivate { { }; + template <typename T> + using is_bool = std::is_same<bool, typename std::decay<T>::type>; + template<typename From, typename To> struct AreArgumentsNarrowedBase<From, To, typename std::enable_if<sizeof(From) && sizeof(To)>::type> : std::integral_constant<bool, (std::is_floating_point<From>::value && std::is_integral<To>::value) || (std::is_floating_point<From>::value && std::is_floating_point<To>::value && sizeof(From) > sizeof(To)) || + ((std::is_pointer<From>::value || std::is_member_pointer<From>::value) && QtPrivate::is_bool<To>::value) || ((std::is_integral<From>::value || std::is_enum<From>::value) && std::is_floating_point<To>::value) || (std::is_integral<From>::value && std::is_integral<To>::value && (sizeof(From) > sizeof(To) diff --git a/src/corelib/mimetypes/qmimeprovider_p.h b/src/corelib/mimetypes/qmimeprovider_p.h index 0629df8a95..c4e712b318 100644 --- a/src/corelib/mimetypes/qmimeprovider_p.h +++ b/src/corelib/mimetypes/qmimeprovider_p.h @@ -140,7 +140,7 @@ public: enum : bool { InternalDatabaseAvailable = false }; QMimeXMLProvider(QMimeDatabasePrivate *db, InternalDatabaseEnum) : QMimeProviderBase(db, QString()) - { Q_UNREACHABLE() }; + { Q_UNREACHABLE(); }; #endif QMimeXMLProvider(QMimeDatabasePrivate *db, const QString &directory); ~QMimeXMLProvider(); diff --git a/src/corelib/serialization/qxmlstream.cpp b/src/corelib/serialization/qxmlstream.cpp index 7ff87885a5..d7fb0d0d41 100644 --- a/src/corelib/serialization/qxmlstream.cpp +++ b/src/corelib/serialization/qxmlstream.cpp @@ -2041,6 +2041,42 @@ QStringRef QXmlStreamReader::dtdSystemId() const return QStringRef(); } +/*! + \since 5.15 + + Returns the maximum amount of characters a single entity is + allowed to expand into. If a single entity expands past the + given limit, the document is not considered well formed. + + \sa setEntityExpansionLimit +*/ +int QXmlStreamReader::entityExpansionLimit() const +{ + Q_D(const QXmlStreamReader); + return d->entityExpansionLimit; +} + +/*! + \since 5.15 + + Sets the maximum amount of characters a single entity is + allowed to expand into to \a limit. If a single entity expands + past the given limit, the document is not considered well formed. + + The limit is there to prevent DoS attacks when loading unknown + XML documents where recursive entity expansion could otherwise + exhaust all available memory. + + The default value for this property is 4096 characters. + + \sa entityExpansionLimit +*/ +void QXmlStreamReader::setEntityExpansionLimit(int limit) +{ + Q_D(QXmlStreamReader); + d->entityExpansionLimit = limit; +} + /*! If the tokenType() is \l StartElement, this function returns the element's namespace declarations. Otherwise an empty vector is returned. diff --git a/src/corelib/serialization/qxmlstream.g b/src/corelib/serialization/qxmlstream.g index 12ecc9bdb2..b623de9505 100644 --- a/src/corelib/serialization/qxmlstream.g +++ b/src/corelib/serialization/qxmlstream.g @@ -285,9 +285,19 @@ public: QHash<QStringView, Entity> entityHash; QHash<QStringView, Entity> parameterEntityHash; QXmlStreamSimpleStack<Entity *>entityReferenceStack; + int entityExpansionLimit = 4096; + int entityLength = 0; inline bool referenceEntity(Entity &entity) { if (entity.isCurrentlyReferenced) { - raiseWellFormedError(QXmlStream::tr("Recursive entity detected.")); + raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected.")); + return false; + } + // entityLength represents the amount of additional characters the + // entity expands into (can be negative for e.g. &). It's used to + // avoid DoS attacks through recursive entity expansions + entityLength += entity.value.size() - entity.name.size() - 2; + if (entityLength > entityExpansionLimit) { + raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit.")); return false; } entity.isCurrentlyReferenced = true; @@ -838,6 +848,8 @@ entity_done ::= ENTITY_DONE; /. case $rule_number: entityReferenceStack.pop()->isCurrentlyReferenced = false; + if (entityReferenceStack.isEmpty()) + entityLength = 0; clearSym(); break; ./ diff --git a/src/corelib/serialization/qxmlstream.h b/src/corelib/serialization/qxmlstream.h index 7d0aa64570..c8647e0465 100644 --- a/src/corelib/serialization/qxmlstream.h +++ b/src/corelib/serialization/qxmlstream.h @@ -426,6 +426,8 @@ public: QStringRef dtdPublicId() const; QStringRef dtdSystemId() const; + int entityExpansionLimit() const; + void setEntityExpansionLimit(int limit); enum Error { NoError, diff --git a/src/corelib/serialization/qxmlstream_p.h b/src/corelib/serialization/qxmlstream_p.h index 9c94e6d434..103b123b10 100644 --- a/src/corelib/serialization/qxmlstream_p.h +++ b/src/corelib/serialization/qxmlstream_p.h @@ -774,9 +774,19 @@ public: QHash<QStringView, Entity> entityHash; QHash<QStringView, Entity> parameterEntityHash; QXmlStreamSimpleStack<Entity *>entityReferenceStack; + int entityExpansionLimit = 4096; + int entityLength = 0; inline bool referenceEntity(Entity &entity) { if (entity.isCurrentlyReferenced) { - raiseWellFormedError(QXmlStream::tr("Recursive entity detected.")); + raiseWellFormedError(QXmlStream::tr("Self-referencing entity detected.")); + return false; + } + // entityLength represents the amount of additional characters the + // entity expands into (can be negative for e.g. &). It's used to + // avoid DoS attacks through recursive entity expansions + entityLength += entity.value.size() - entity.name.size() - 2; + if (entityLength > entityExpansionLimit) { + raiseWellFormedError(QXmlStream::tr("Entity expands to more characters than the entity expansion limit.")); return false; } entity.isCurrentlyReferenced = true; @@ -1308,6 +1318,8 @@ bool QXmlStreamReaderPrivate::parse() case 10: entityReferenceStack.pop()->isCurrentlyReferenced = false; + if (entityReferenceStack.isEmpty()) + entityLength = 0; clearSym(); break; diff --git a/src/corelib/thread/qrunnable.cpp b/src/corelib/thread/qrunnable.cpp index 5b883a05da..32f3cd657e 100644 --- a/src/corelib/thread/qrunnable.cpp +++ b/src/corelib/thread/qrunnable.cpp @@ -115,29 +115,29 @@ QRunnable::~QRunnable() class FunctionRunnable : public QRunnable { - std::function<void()> m_functor; + std::function<void()> m_functionToRun; public: - FunctionRunnable(std::function<void()> functor) : m_functor(std::move(functor)) + FunctionRunnable(std::function<void()> functionToRun) : m_functionToRun(std::move(functionToRun)) { } void run() override { - m_functor(); + m_functionToRun(); } }; /*! \since 5.15 - Creates a QRunnable that calls \a fun in run(). + Creates a QRunnable that calls \a functionToRun in run(). Auto-deletion is enabled by default. \sa run(), autoDelete() */ -QRunnable *QRunnable::create(std::function<void()> fun) +QRunnable *QRunnable::create(std::function<void()> functionToRun) { - return new FunctionRunnable(std::move(fun)); + return new FunctionRunnable(std::move(functionToRun)); } QT_END_NAMESPACE diff --git a/src/corelib/thread/qrunnable.h b/src/corelib/thread/qrunnable.h index c13aa3fa8c..26b6b991ac 100644 --- a/src/corelib/thread/qrunnable.h +++ b/src/corelib/thread/qrunnable.h @@ -60,7 +60,7 @@ public: QRunnable() : ref(0) { } virtual ~QRunnable(); - static QRunnable *create(std::function<void()> fun); + static QRunnable *create(std::function<void()> functionToRun); bool autoDelete() const { return ref != -1; } void setAutoDelete(bool _autoDelete) { ref = _autoDelete ? 0 : -1; } diff --git a/src/corelib/thread/qthreadpool.cpp b/src/corelib/thread/qthreadpool.cpp index d1875a69a9..a9352c3894 100644 --- a/src/corelib/thread/qthreadpool.cpp +++ b/src/corelib/thread/qthreadpool.cpp @@ -515,16 +515,16 @@ void QThreadPool::start(QRunnable *runnable, int priority) \overload \since 5.15 - Reserves a thread and uses it to run \a fun, unless this thread will + Reserves a thread and uses it to run \a functionToRun, unless this thread will make the current thread count exceed maxThreadCount(). In that case, - \a fun is added to a run queue instead. The \a priority argument can + \a functionToRun is added to a run queue instead. The \a priority argument can be used to control the run queue's order of execution. */ -void QThreadPool::start(std::function<void()> fun, int priority) +void QThreadPool::start(std::function<void()> functionToRun, int priority) { - if (!fun) + if (!functionToRun) return; - start(QRunnable::create(std::move(fun)), priority); + start(QRunnable::create(std::move(functionToRun)), priority); } /*! @@ -561,17 +561,17 @@ bool QThreadPool::tryStart(QRunnable *runnable) /*! \overload \since 5.15 - Attempts to reserve a thread to run \a fun. + Attempts to reserve a thread to run \a functionToRun. If no threads are available at the time of calling, then this function - does nothing and returns \c false. Otherwise, \a fun is run immediately + does nothing and returns \c false. Otherwise, \a functionToRun is run immediately using one available thread and this function returns \c true. */ -bool QThreadPool::tryStart(std::function<void()> fun) +bool QThreadPool::tryStart(std::function<void()> functionToRun) { - if (!fun) + if (!functionToRun) return false; - return tryStart(QRunnable::create(std::move(fun))); + return tryStart(QRunnable::create(std::move(functionToRun))); } /*! \property QThreadPool::expiryTimeout diff --git a/src/corelib/thread/qthreadpool.h b/src/corelib/thread/qthreadpool.h index 2eede44eca..e3691ab010 100644 --- a/src/corelib/thread/qthreadpool.h +++ b/src/corelib/thread/qthreadpool.h @@ -72,8 +72,8 @@ public: void start(QRunnable *runnable, int priority = 0); bool tryStart(QRunnable *runnable); - void start(std::function<void()> fun, int priority = 0); - bool tryStart(std::function<void()> fun); + void start(std::function<void()> functionToRun, int priority = 0); + bool tryStart(std::function<void()> functionToRun); int expiryTimeout() const; void setExpiryTimeout(int expiryTimeout); diff --git a/src/corelib/time/qdatetimeparser.cpp b/src/corelib/time/qdatetimeparser.cpp index 790c20004a..2a19611493 100644 --- a/src/corelib/time/qdatetimeparser.cpp +++ b/src/corelib/time/qdatetimeparser.cpp @@ -1539,6 +1539,14 @@ QDateTimeParser::parse(QString input, int position, const QDateTime &defaultValu text = scan.input = input; // Set spec *after* all checking, so validity is a property of the string: scan.value = scan.value.toTimeSpec(spec); + + /* + However, even with a valid string we might have ended up with an invalid datetime: + the non-existent hour during dst changes, for instance. + */ + if (!scan.value.isValid() && scan.state == Acceptable) + scan.state = Intermediate; + return scan; } diff --git a/src/corelib/tools/qhash.h b/src/corelib/tools/qhash.h index 47fa0520d9..59883e3968 100644 --- a/src/corelib/tools/qhash.h +++ b/src/corelib/tools/qhash.h @@ -324,7 +324,7 @@ public: QHashData::Node *i; public: -#if QT_DEPRECATED_SINCE(5, 15) +#if QT_DEPRECATED_WARNINGS_SINCE < QT_VERSION_CHECK(5, 15, 0) typedef std::bidirectional_iterator_tag iterator_category; #else typedef std::forward_iterator_tag iterator_category; @@ -354,23 +354,23 @@ public: return r; } #if QT_DEPRECATED_SINCE(5, 15) - inline QT_DEPRECATED iterator &operator--() + inline QT_DEPRECATED_VERSION_5_15 iterator &operator--() { i = QHashData::previousNode(i); return *this; } - inline QT_DEPRECATED iterator operator--(int) + inline QT_DEPRECATED_VERSION_5_15 iterator operator--(int) { iterator r = *this; i = QHashData::previousNode(i); return r; } - inline QT_DEPRECATED iterator operator+(int j) const + inline QT_DEPRECATED_VERSION_5_15 iterator operator+(int j) const { iterator r = *this; if (j > 0) while (j--) ++r; else while (j++) --r; return r; } - inline QT_DEPRECATED iterator operator-(int j) const { return operator+(-j); } - inline QT_DEPRECATED iterator &operator+=(int j) { return *this = *this + j; } - inline QT_DEPRECATED iterator &operator-=(int j) { return *this = *this - j; } - friend inline QT_DEPRECATED iterator operator+(int j, iterator k) { return k + j; } + inline QT_DEPRECATED_VERSION_5_15 iterator operator-(int j) const { return operator+(-j); } + inline QT_DEPRECATED_VERSION_5_15 iterator &operator+=(int j) { return *this = *this + j; } + inline QT_DEPRECATED_VERSION_5_15 iterator &operator-=(int j) { return *this = *this - j; } + friend inline QT_DEPRECATED_VERSION_5_15 iterator operator+(int j, iterator k) { return k + j; } #endif inline bool operator==(const const_iterator &o) const { return i == o.i; } @@ -387,7 +387,7 @@ public: QHashData::Node *i; public: -#if QT_DEPRECATED_SINCE(5, 15) +#if QT_DEPRECATED_WARNINGS_SINCE < QT_VERSION_CHECK(5, 15, 0) typedef std::bidirectional_iterator_tag iterator_category; #else typedef std::forward_iterator_tag iterator_category; @@ -420,23 +420,23 @@ public: return r; } #if QT_DEPRECATED_SINCE(5, 15) - inline QT_DEPRECATED const_iterator &operator--() + inline QT_DEPRECATED_VERSION_5_15 const_iterator &operator--() { i = QHashData::previousNode(i); return *this; } - inline QT_DEPRECATED const_iterator operator--(int) + inline QT_DEPRECATED_VERSION_5_15 const_iterator operator--(int) { const_iterator r = *this; i = QHashData::previousNode(i); return r; } - inline QT_DEPRECATED const_iterator operator+(int j) const + inline QT_DEPRECATED_VERSION_5_15 const_iterator operator+(int j) const { const_iterator r = *this; if (j > 0) while (j--) ++r; else while (j++) --r; return r; } - inline QT_DEPRECATED const_iterator operator-(int j) const { return operator+(-j); } - inline QT_DEPRECATED const_iterator &operator+=(int j) { return *this = *this + j; } - inline QT_DEPRECATED const_iterator &operator-=(int j) { return *this = *this - j; } - friend inline QT_DEPRECATED const_iterator operator+(int j, const_iterator k) + inline QT_DEPRECATED_VERSION_5_15 const_iterator operator-(int j) const { return operator+(-j); } + inline QT_DEPRECATED_VERSION_5_15 const_iterator &operator+=(int j) { return *this = *this + j; } + inline QT_DEPRECATED_VERSION_5_15 const_iterator &operator-=(int j) { return *this = *this - j; } + friend inline QT_DEPRECATED_VERSION_5_15 const_iterator operator+(int j, const_iterator k) { return k + j; } @@ -466,12 +466,12 @@ public: inline key_iterator &operator++() { ++i; return *this; } inline key_iterator operator++(int) { return key_iterator(i++);} #if QT_DEPRECATED_SINCE(5, 15) - inline QT_DEPRECATED key_iterator &operator--() + inline QT_DEPRECATED_VERSION_5_15 key_iterator &operator--() { --i; return *this; } - inline QT_DEPRECATED key_iterator operator--(int) { return key_iterator(i--); } + inline QT_DEPRECATED_VERSION_5_15 key_iterator operator--(int) { return key_iterator(i--); } #endif const_iterator base() const { return i; } }; @@ -1302,18 +1302,18 @@ public: return false; } #if QT_DEPRECATED_SINCE(5, 15) - inline QT_DEPRECATED bool hasPrevious() const { return i != c.constBegin(); } - inline QT_DEPRECATED Item previous() + inline QT_DEPRECATED_VERSION_5_15 bool hasPrevious() const { return i != c.constBegin(); } + inline QT_DEPRECATED_VERSION_5_15 Item previous() { n = --i; return n; } - inline QT_DEPRECATED Item peekPrevious() const + inline QT_DEPRECATED_VERSION_5_15 Item peekPrevious() const { const_iterator p = i; return --p; } - inline bool QT_DEPRECATED findPrevious(const T &t) + inline bool QT_DEPRECATED_VERSION_5_15 findPrevious(const T &t) { while (i != c.constBegin()) if (*(n = --i) == t) @@ -1399,18 +1399,18 @@ public: return false; } #if QT_DEPRECATED_SINCE(5, 15) - inline QT_DEPRECATED bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } - inline QT_DEPRECATED Item previous() + inline QT_DEPRECATED_VERSION_5_15 bool hasPrevious() const { return const_iterator(i) != c->constBegin(); } + inline QT_DEPRECATED_VERSION_5_15 Item previous() { n = --i; return n; } - inline QT_DEPRECATED Item peekPrevious() const + inline QT_DEPRECATED_VERSION_5_15 Item peekPrevious() const { iterator p = i; return --p; } - inline QT_DEPRECATED bool findPrevious(const T &t) + inline QT_DEPRECATED_VERSION_5_15 bool findPrevious(const T &t) { while (const_iterator(i) != c->constBegin()) if (*(n = --i) == t) |