QTextFormatCollection: replace copy ctor and op= with clear()

operator=, which was only used for clearing, wasn't clearing the hash.
This led to a mismatch between the vector and the hash (given that the hash
points into the vector).

Spotted by interrupting kmail in gdb, and it was in this code
iterating over a 2000 entries hash (the first vector entries not matching
the hash, this code keep appending new entries for the same formats).

This fixes QTBUG-8862 again, the initial fix having been accidentally
reverted in 467b15a.

Change-Id: Ia34b3d002a0199e1930431a4bbdb2ec981ed4ffc
Task-number: QTBUG-8862
Reviewed-by: Olivier Goffart (Woboq GmbH) <ogoffart@woboq.com>
bb10
David Faure 2017-02-20 10:55:59 +01:00
parent 8e95828475
commit 90b48a70ff
4 changed files with 39 additions and 17 deletions

View File

@ -265,7 +265,7 @@ void QTextDocumentPrivate::clear()
unreachableCharacterCount = 0;
modifiedState = 0;
modified = false;
formats = QTextFormatCollection();
formats.clear();
int len = fragments.length();
fragments.clear();
blocks.clear();

View File

@ -3371,24 +3371,17 @@ QTextTableCellFormat::QTextTableCellFormat(const QTextFormat &fmt)
// ------------------------------------------------------
QTextFormatCollection::QTextFormatCollection(const QTextFormatCollection &rhs)
{
formats = rhs.formats;
objFormats = rhs.objFormats;
}
QTextFormatCollection &QTextFormatCollection::operator=(const QTextFormatCollection &rhs)
{
formats = rhs.formats;
objFormats = rhs.objFormats;
return *this;
}
QTextFormatCollection::~QTextFormatCollection()
{
}
void QTextFormatCollection::clear()
{
formats.clear();
objFormats.clear();
hashes.clear();
}
int QTextFormatCollection::indexForFormat(const QTextFormat &format)
{
uint hash = getHash(format.d, format.format_type);

View File

@ -63,8 +63,7 @@ public:
QTextFormatCollection() {}
~QTextFormatCollection();
QTextFormatCollection(const QTextFormatCollection &rhs);
QTextFormatCollection &operator=(const QTextFormatCollection &rhs);
void clear();
inline QTextFormat objectFormat(int objectIndex) const
{ return format(objectFormatIndex(objectIndex)); }
@ -104,6 +103,8 @@ public:
private:
QFont defaultFnt;
Q_DISABLE_COPY(QTextFormatCollection)
};
QT_END_NAMESPACE

View File

@ -60,6 +60,7 @@ private slots:
void setFont();
void setFont_collection_data();
void setFont_collection();
void clearCollection();
};
/*! \internal
@ -640,5 +641,32 @@ void tst_QTextFormat::setFont_collection()
}
}
void tst_QTextFormat::clearCollection()
{
QTextFormatCollection collection;
QFont f;
f.setUnderline(true);
collection.setDefaultFont(f);
QTextCharFormat charFormat;
charFormat.setFontStyleHint(QFont::SansSerif);
int formatIndex = collection.indexForFormat(charFormat);
QCOMPARE(formatIndex, 0);
QTextCharFormat charFormat2;
charFormat2.setUnderlineStyle(QTextCharFormat::SingleUnderline);
int formatIndex2 = collection.indexForFormat(charFormat2);
QCOMPARE(formatIndex2, 1);
QCOMPARE(collection.formats.count(), 2);
QCOMPARE(collection.hashes.count(), 2);
QCOMPARE(collection.defaultFont(), f);
collection.clear();
QCOMPARE(collection.formats.count(), 0);
QCOMPARE(collection.hashes.count(), 0);
QCOMPARE(collection.indexForFormat(charFormat2), 0);
QCOMPARE(collection.formats.count(), 1);
QCOMPARE(collection.hashes.count(), 1);
QCOMPARE(collection.defaultFont(), f); // kept, QTextDocument::clear or setPlainText should not reset the font set by setDefaultFont
}
QTEST_MAIN(tst_QTextFormat)
#include "tst_qtextformat.moc"