summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/corelib/tools/qmap.h18
-rw-r--r--tests/manual/corelib/tools/qmap/main.cpp111
-rw-r--r--tests/manual/corelib/tools/qmap/qmaptest.pro2
3 files changed, 131 insertions, 0 deletions
diff --git a/src/corelib/tools/qmap.h b/src/corelib/tools/qmap.h
index 449fcbca0a..8c15afd9f8 100644
--- a/src/corelib/tools/qmap.h
+++ b/src/corelib/tools/qmap.h
@@ -557,6 +557,18 @@ public:
private:
void detach_helper();
+ bool isValidIterator(const const_iterator &ci) const
+ {
+#if defined(QT_DEBUG) && !defined(Q_MAP_NO_ITERATOR_DEBUG)
+ const QMapNodeBase *n = ci.i;
+ while (n->parent())
+ n = n->parent();
+ return n->left == d->root();
+#else
+ Q_UNUSED(ci);
+ return true;
+#endif
+ }
};
template <class Key, class T>
@@ -670,6 +682,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insert(const_iterator pos, const K
if (d->ref.isShared())
return this->insert(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insert", "The specified const_iterator argument 'it' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -753,6 +767,8 @@ typename QMap<Key, T>::iterator QMap<Key, T>::insertMulti(const_iterator pos, co
if (d->ref.isShared())
return this->insertMulti(akey, avalue);
+ Q_ASSERT_X(isValidIterator(pos), "QMap::insertMulti", "The specified const_iterator argument 'pos' is invalid");
+
if (pos == constEnd()) {
// Hint is that the Node is larger than (or equal to) the largest value.
Node *n = static_cast<Node *>(pos.i->left);
@@ -895,6 +911,8 @@ Q_OUTOFLINE_TEMPLATE typename QMap<Key, T>::iterator QMap<Key, T>::erase(iterato
if (it == iterator(d->end()))
return it;
+ Q_ASSERT_X(isValidIterator(const_iterator(it)), "QMap::erase", "The specified iterator argument 'it' is invalid");
+
Node *n = it.i;
++it;
d->deleteNode(n);
diff --git a/tests/manual/corelib/tools/qmap/main.cpp b/tests/manual/corelib/tools/qmap/main.cpp
new file mode 100644
index 0000000000..0d88e3f170
--- /dev/null
+++ b/tests/manual/corelib/tools/qmap/main.cpp
@@ -0,0 +1,111 @@
+/****************************************************************************
+**
+** Copyright (C) 2012 Thorbjørn Lund Martsum - tmartsum[at]gmail.com
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the test suite of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+//#define Q_NO_DEBUGMAP_PARENT_TEST
+// Comment in line above to skip the parent test.
+#include <QtCore/QMap>
+#include <QDebug>
+
+void noBugErase()
+{
+ QMap<int, int> a, b;
+ a[10] = 11;
+ a[11] = 12;
+ b = a;
+ b.erase(b.begin());
+}
+
+void noBugInsertWithHints()
+{
+ QMap<int, int> a;
+ QMap<int, int> b;
+ for (int u = 100; u < 10000; u += 20)
+ a.insert(u, u);
+ b = a;
+ QMap<int, int>::const_iterator b_ite(b.begin()); // b.begin() ensures correct detach()
+ ++b_ite;
+ b.insert(b_ite, 501, 501);
+ b.insert(b_ite, 115, 115);
+ QMap<int, int> c;
+ c = b;
+ c.setSharable(false);
+}
+
+void testInsertWithHintCorruption()
+{
+ qDebug() << "Starting testInsertWithHintCorruption";
+
+ QMap<int, int> a;
+ QMap<int, int> b;
+ for (int u = 100; u < 10000; u += 20)
+ a.insert(u, u);
+ b = a;
+ QMap<int, int>::const_iterator b_ite = b.constBegin();
+ ++b_ite;
+ b.insert(b_ite, 501, 501);
+ b.insert(b_ite, 115, 115); // insert with wrong hint.
+ QMap<int, int> c;
+ c = b;
+ c.setSharable(false);
+ qDebug() << "End of testInsertWithHintCorruption - failed silently";
+}
+
+void testEraseCorruption()
+{
+ qDebug() << "Starting testEraseCorruption";
+
+ QMap<int, int> a, b;
+ a[10] = 11;
+ a[11] = 12;
+ b = a;
+ b.erase(a.begin());
+ qDebug() << "End of testEraseCorruption - failed silently";
+}
+
+int main()
+{
+ noBugErase();
+ noBugInsertWithHints();
+
+ // testEraseCorruption();
+ testInsertWithHintCorruption();
+ return 0;
+}
diff --git a/tests/manual/corelib/tools/qmap/qmaptest.pro b/tests/manual/corelib/tools/qmap/qmaptest.pro
new file mode 100644
index 0000000000..fbe7013144
--- /dev/null
+++ b/tests/manual/corelib/tools/qmap/qmaptest.pro
@@ -0,0 +1,2 @@
+TEMPLATE = app
+SOURCES = main.cpp