Fix crash when detaching dangling QTextCursor
When a QTextCursor survives its QTextDocument, the internal QTextDocumentPrivate pointer is set to null. There are checks for this in all the QTextCursor functions to skip out early if such a QTextCursor is used. However, when executing the "if (d->priv)" condition in setters, this will access the non-const operator->() of QSharedDataPointer and detach the QTextCursorPrivate, and in the copy constructor of this class, there was an unprotected call into priv->addCursor(). In theory, we could cast all the checks for d->priv to avoid detaching, but in practice this doesn't matter, since the setters will typically detach anyway later on. [ChangeLog][QtGui][Text] Fixed a crash that can happen when calling a setter on a QTextCursor after its QTextDocument has been deleted. Task-number: QTBUG-70293 Change-Id: I8f6dc5bb344d1d824f673c0c220b68b7fee237a8 Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com> Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>bb10
parent
9601ad4e27
commit
720e243d88
|
|
@ -80,7 +80,8 @@ QTextCursorPrivate::QTextCursorPrivate(const QTextCursorPrivate &rhs)
|
|||
visualNavigation = rhs.visualNavigation;
|
||||
keepPositionOnInsert = rhs.keepPositionOnInsert;
|
||||
changed = rhs.changed;
|
||||
priv->addCursor(this);
|
||||
if (priv != nullptr)
|
||||
priv->addCursor(this);
|
||||
}
|
||||
|
||||
QTextCursorPrivate::~QTextCursorPrivate()
|
||||
|
|
|
|||
|
|
@ -137,6 +137,7 @@ private slots:
|
|||
void cursorPositionWithBlockUndoAndRedo3();
|
||||
|
||||
void joinNonEmptyRemovedBlockUserState();
|
||||
void crashOnDetachingDanglingCursor();
|
||||
|
||||
private:
|
||||
int blockCount();
|
||||
|
|
@ -1974,5 +1975,14 @@ void tst_QTextCursor::joinNonEmptyRemovedBlockUserState()
|
|||
QCOMPARE(cursor.block().userState(), 10);
|
||||
}
|
||||
|
||||
void tst_QTextCursor::crashOnDetachingDanglingCursor()
|
||||
{
|
||||
QTextDocument *document = new QTextDocument;
|
||||
QTextCursor cursor(document);
|
||||
QTextCursor cursor2 = cursor;
|
||||
delete document;
|
||||
cursor2.setPosition(0); // Don't crash here
|
||||
}
|
||||
|
||||
QTEST_MAIN(tst_QTextCursor)
|
||||
#include "tst_qtextcursor.moc"
|
||||
|
|
|
|||
Loading…
Reference in New Issue