diff options
author | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-03-13 14:49:46 +0200 |
---|---|---|
committer | Miikka Heikkinen <miikka.heikkinen@qt.io> | 2019-03-13 14:13:18 +0000 |
commit | 3560fdfbc9314d591c1c605441ea40ad941e234b (patch) | |
tree | 6bbe6d5c0afd5580e74c9bab8b49505cfaf0d987 /src | |
parent | 24abcb6da0158363285e5b75cdf24a6fa4d1bd3b (diff) |
Fix crash on shutdown
All copies of Q3DSSourceInfo shared the same m_internalVariantList
strings, which caused problems at cleanup time. Another potential issue
caused by this would be having multiple Q3DSSourceInfo instances alive
and updating variant list on one of them. This would destroy the
strings referred by other copies.
Fixed by accessing m_internalVariantList and m_variantFilter via a
shared pointer.
Task-number: QT3DS-3155
Change-Id: I1efdace26e3ed3d09ce1c8f0ad6aadf44d1f5c16
Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io>
Reviewed-by: Pasi Keränen <pasi.keranen@qt.io>
Diffstat (limited to 'src')
-rw-r--r-- | src/runtime/q3dssourceinfo_p.h | 55 |
1 files changed, 38 insertions, 17 deletions
diff --git a/src/runtime/q3dssourceinfo_p.h b/src/runtime/q3dssourceinfo_p.h index 2e153d6..0c0ae01 100644 --- a/src/runtime/q3dssourceinfo_p.h +++ b/src/runtime/q3dssourceinfo_p.h @@ -53,13 +53,31 @@ QT_BEGIN_NAMESPACE class Q3DSV_PRIVATE_EXPORT Q3DSSourceInfo { public: - Q3DSSourceInfo() { } + Q3DSSourceInfo() + { + m_variantFilter.reset(new QHash<QStringRef, QVector<QStringRef>>); + m_internalVariantList.reset(new QVector<QString>); + } ~Q3DSSourceInfo() { - for (auto str : qAsConst(m_internalVariantList)) - delete str; - m_internalVariantList.clear(); + m_variantFilter.reset(); + m_internalVariantList.reset(); + } + + Q3DSSourceInfo(const Q3DSSourceInfo &other) + { + operator=(other); + } + + inline Q3DSSourceInfo &operator=(const Q3DSSourceInfo &other) + { + m_url = other.m_url; + m_fileName = other.m_fileName; + m_variantList = other.m_variantList; + m_internalVariantList = other.m_internalVariantList; + m_variantFilter = other.m_variantFilter; + return *this; } inline bool operator==(const Q3DSSourceInfo &other) @@ -97,34 +115,37 @@ public: // Store the QStringList to be returned from the API m_variantList = variantList; - for (auto str : qAsConst(m_internalVariantList)) - delete str; - m_internalVariantList.clear(); + // Note that all instances that share the filter lists will get updated + m_variantFilter->clear(); + m_internalVariantList->clear(); // Build a fixed (in mem location) list of the variant strings - for (auto tag: variantList) - m_internalVariantList.append(new QString(tag)); + for (const auto &tag : variantList) + m_internalVariantList->append(tag); // Parse the variantGroup:variant list to map using the fixed list - m_variantFilter.clear(); - for (auto tag : qAsConst(m_internalVariantList)) { - QStringRef refTag = QStringRef(tag); + const auto &internalList = *m_internalVariantList.data(); + for (const auto &tag : internalList) { + QStringRef refTag = QStringRef(&tag); int separatorIdx = refTag.indexOf(QLatin1Char(':')); QStringRef group = refTag.left(separatorIdx); QStringRef variant = refTag.mid(separatorIdx + 1); - m_variantFilter[group].append(variant); + (*m_variantFilter)[group].append(variant); } } inline const QStringList &variantList() const { return m_variantList; } - inline const QHash<QStringRef, QVector<QStringRef>> &variantMap() const { return m_variantFilter; } + inline const QHash<QStringRef, QVector<QStringRef>> &variantMap() const + { + return *m_variantFilter.data(); + } private: QUrl m_url; - QStringList m_variantList; - QList<QString*> m_internalVariantList; QString m_fileName; - QHash<QStringRef, QVector<QStringRef>> m_variantFilter; + QStringList m_variantList; + QSharedPointer<QVector<QString>> m_internalVariantList; + QSharedPointer<QHash<QStringRef, QVector<QStringRef>>> m_variantFilter; }; QT_END_NAMESPACE |