QVariant: Fix flags for type-erased associative iterator key
The flags here are passed to a private QVariant constructor, and they really represent a boolean - IsPointer or not. Because the flag for the key_type was incorrectly populated with the flag for the value_type, memory would be corrupted when using a mapping type whose value_type is a pointer, but whose key type was not, such as QMap<QString, int*> This typo has been there since the concept was introduced in commit v5.2.0-alpha1~807 (Add container access functionality for associative containers in QVariant., 2013-04-05). Task-number: QTBUG-52246 Change-Id: I9ecb13c603015eed2dc2ca43947fa0ecd6be8b5a Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
This commit is contained in:
parent
ad864ef194
commit
bedf0367ac
@ -1226,7 +1226,7 @@ public:
|
||||
|
||||
inline void destroyIter() { _destroyIter(&_iterator); }
|
||||
|
||||
inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_value); }
|
||||
inline VariantData getCurrentKey() const { return _getKey(&_iterator, _metaType_id_key, _metaType_flags_key); }
|
||||
inline VariantData getCurrentValue() const { return _getValue(&_iterator, _metaType_id_value, _metaType_flags_value); }
|
||||
|
||||
inline void find(const VariantData &key)
|
||||
|
@ -280,6 +280,8 @@ private slots:
|
||||
void compareSanity_data();
|
||||
void compareSanity();
|
||||
|
||||
void accessSequentialContainerKey();
|
||||
|
||||
private:
|
||||
void dataStream_data(QDataStream::Version version);
|
||||
void loadQVariantFromDataStream(QDataStream::Version version);
|
||||
@ -4733,5 +4735,30 @@ void tst_QVariant::compareSanity()
|
||||
}
|
||||
}
|
||||
|
||||
void tst_QVariant::accessSequentialContainerKey()
|
||||
{
|
||||
QString nameResult;
|
||||
|
||||
{
|
||||
QMap<QString, QObject*> mapping;
|
||||
QString name = QString::fromLatin1("Seven");
|
||||
mapping.insert(name, Q_NULLPTR);
|
||||
|
||||
QVariant variant = QVariant::fromValue(mapping);
|
||||
|
||||
QAssociativeIterable iterable = variant.value<QAssociativeIterable>();
|
||||
QAssociativeIterable::const_iterator iit = iterable.begin();
|
||||
const QAssociativeIterable::const_iterator end = iterable.end();
|
||||
for ( ; iit != end; ++iit) {
|
||||
nameResult += iit.key().toString();
|
||||
}
|
||||
} // Destroy mapping
|
||||
// Regression test for QTBUG-52246 - no memory corruption/double deletion
|
||||
// of the string key.
|
||||
|
||||
QCOMPARE(nameResult, QStringLiteral("Seven"));
|
||||
}
|
||||
|
||||
|
||||
QTEST_MAIN(tst_QVariant)
|
||||
#include "tst_qvariant.moc"
|
||||
|
Loading…
Reference in New Issue
Block a user