Fix a crash in QPlainTextEdit::documentChanged

The layout for an invalid block is very likely to be null, it
shouldn't be accessed without checking the block's validity first.
We can make the check a bit more conservative and simply check that
the block isn't empty.

Change-Id: Ic1459a6168b1b8ce36e9c6d019dc28653676efbe
Task-number: QTBUG-43562
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
This commit is contained in:
Pierre Rossi 2015-01-07 16:16:23 +01:00
parent 7c9497ad6a
commit 890ae41d06
2 changed files with 34 additions and 2 deletions

View File

@ -288,8 +288,7 @@ void QPlainTextDocumentLayout::documentChanged(int from, int charsRemoved, int c
if (changeStartBlock == changeEndBlock && newBlockCount == d->blockCount) {
QTextBlock block = changeStartBlock;
int blockLineCount = block.layout()->lineCount();
if (block.isValid() && blockLineCount) {
if (block.isValid() && block.length()) {
QRectF oldBr = blockBoundingRect(block);
layoutBlock(block);
QRectF newBr = blockBoundingRect(block);

View File

@ -148,6 +148,7 @@ private slots:
#endif
void layoutAfterMultiLineRemove();
void undoCommandRemovesAndReinsertsBlock();
void taskQTBUG_43562_lineCountCrash();
private:
void createSelection();
@ -1629,5 +1630,37 @@ void tst_QPlainTextEdit::undoCommandRemovesAndReinsertsBlock()
}
class ContentsChangedFunctor {
public:
ContentsChangedFunctor(QPlainTextEdit *t) : textEdit(t) {}
void operator()(int, int, int)
{
QTextCursor c(textEdit->textCursor());
c.beginEditBlock();
c.movePosition(QTextCursor::Start);
c.movePosition(QTextCursor::End, QTextCursor::KeepAnchor);
c.setCharFormat(QTextCharFormat());
c.endEditBlock();
}
private:
QPlainTextEdit *textEdit;
};
void tst_QPlainTextEdit::taskQTBUG_43562_lineCountCrash()
{
connect(ed->document(), &QTextDocument::contentsChange, ContentsChangedFunctor(ed));
// Don't crash
QTest::keyClicks(ed, "Some text");
QTest::keyClick(ed, Qt::Key_Left);
QTest::keyClick(ed, Qt::Key_Right);
QTest::keyClick(ed, Qt::Key_A);
QTest::keyClick(ed, Qt::Key_Left);
QTest::keyClick(ed, Qt::Key_Right);
QTest::keyClick(ed, Qt::Key_Space);
QTest::keyClicks(ed, "nd some more");
disconnect(ed->document(), SIGNAL(contentsChange(int, int, int)), 0, 0);
}
QTEST_MAIN(tst_QPlainTextEdit)
#include "tst_qplaintextedit.moc"