diff options
author | Marc Mutz <marc.mutz@kdab.com> | 2016-07-01 17:28:37 +0200 |
---|---|---|
committer | Marc Mutz <marc.mutz@kdab.com> | 2016-07-06 10:34:43 +0000 |
commit | 631b143b3f6650b5761ac2c78e7936e1594b6e4f (patch) | |
tree | 5a3d38d4d13bb4890bd22c3db2beaa6ebed6e452 | |
parent | a91d0dd369313dfa8865f99e590b868146cb4388 (diff) |
QComboBox: fix crash on setEditable(false) called from editTextChanged()
QLineEdit::setText() emits QLineEdit::textChanged(), which is
connected to QComboBox::editTextChanged(). When a user slot
connected to editTextChanged() sets QComboBox::editable to
false, the line edit will be deleted in setEditable() and
when control returns to QComboBoxPrivate::setCurrentIndex(),
the formerly non-null 'lineEdit' has changed to nullptr,
leading to a nullptr dereference when attempting to set the
completionPrefix on lineEdit->completer().
Fix by re-checking 'lineEdit' after returning from the
QLineEdit::setText() call.
Add a test.
Task-number: QTBUG-54191
Change-Id: I94154796cfde73fb490f8471c48b9d6f62825a92
Reviewed-by: Friedemann Kleint <Friedemann.Kleint@qt.io>
-rw-r--r-- | src/widgets/widgets/qcombobox.cpp | 4 | ||||
-rw-r--r-- | tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp | 25 |
2 files changed, 27 insertions, 2 deletions
diff --git a/src/widgets/widgets/qcombobox.cpp b/src/widgets/widgets/qcombobox.cpp index 2abcd4d3c2..181671c493 100644 --- a/src/widgets/widgets/qcombobox.cpp +++ b/src/widgets/widgets/qcombobox.cpp @@ -2100,9 +2100,9 @@ void QComboBoxPrivate::setCurrentIndex(const QModelIndex &mi) if (lineEdit) { const QString newText = itemText(normalized); if (lineEdit->text() != newText) { - lineEdit->setText(newText); + lineEdit->setText(newText); // may cause lineEdit -> nullptr (QTBUG-54191) #ifndef QT_NO_COMPLETER - if (lineEdit->completer()) + if (lineEdit && lineEdit->completer()) lineEdit->completer()->setCompletionPrefix(newText); #endif } diff --git a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp index ae516639a6..15bf686699 100644 --- a/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp +++ b/tests/auto/widgets/widgets/qcombobox/tst_qcombobox.cpp @@ -161,6 +161,7 @@ private slots: void itemData(); void task_QTBUG_31146_popupCompletion(); void task_QTBUG_41288_completerChangesCurrentIndex(); + void task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly(); void keyboardSelection(); void setCustomModelAndView(); void updateDelegateOnEditableChange(); @@ -3124,6 +3125,30 @@ void tst_QComboBox::task_QTBUG_41288_completerChangesCurrentIndex() } } +namespace { + struct SetReadOnly { + QComboBox *cb; + explicit SetReadOnly(QComboBox *cb) : cb(cb) {} + void operator()() const + { cb->setEditable(false); } + }; +} + +void tst_QComboBox::task_QTBUG_54191_slotOnEditTextChangedSetsComboBoxToReadOnly() +{ + QComboBox cb; + cb.addItems(QStringList() << "one" << "two"); + cb.setEditable(true); + cb.setCurrentIndex(0); + + connect(&cb, &QComboBox::editTextChanged, + SetReadOnly(&cb)); + + cb.setCurrentIndex(1); + // the real test is that it didn't crash... + QCOMPARE(cb.currentIndex(), 1); +} + void tst_QComboBox::keyboardSelection() { QComboBox comboBox; |