Fix a crash in QFileDialog when selecting an invalid name filter.

When nameDetailsVisible is set to false and an invalid/empty
string is passed to selectNameFilter(), the regexp used to
strip the filter off the suffixes returns empty and a crash
occurs.

Change-Id: I926ea49514ff25a103977d8121fca1cf83d647f5
Reviewed-by: Miikka Heikkinen <miikka.heikkinen@digia.com>
Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
This commit is contained in:
Friedemann Kleint 2012-10-26 10:44:00 +02:00 committed by The Qt Project
parent 8ac2ea94d3
commit d0aa81ee10
2 changed files with 53 additions and 6 deletions

View File

@ -1201,9 +1201,11 @@ void QFileDialog::selectNameFilter(const QString &filter)
d->selectNameFilter_sys(filter);
return;
}
int i;
int i = -1;
if (testOption(HideNameFilterDetails)) {
i = d->qFileDialogUi->fileTypeCombo->findText(qt_strip_filters(qt_make_filter_list(filter)).first());
const QStringList filters = qt_strip_filters(qt_make_filter_list(filter));
if (!filters.isEmpty())
i = d->qFileDialogUi->fileTypeCombo->findText(filters.first());
} else {
i = d->qFileDialogUi->fileTypeCombo->findText(filter);
}
@ -1770,7 +1772,7 @@ QString QFileDialog::getOpenFileName(QWidget *parent,
// create a qt dialog
QFileDialog dialog(args);
if (selectedFilter)
if (selectedFilter && !selectedFilter->isEmpty())
dialog.selectNameFilter(*selectedFilter);
if (dialog.exec() == QDialog::Accepted) {
if (selectedFilter)
@ -1855,7 +1857,7 @@ QStringList QFileDialog::getOpenFileNames(QWidget *parent,
// create a qt dialog
QFileDialog dialog(args);
if (selectedFilter)
if (selectedFilter && !selectedFilter->isEmpty())
dialog.selectNameFilter(*selectedFilter);
if (dialog.exec() == QDialog::Accepted) {
if (selectedFilter)
@ -1942,7 +1944,7 @@ QString QFileDialog::getSaveFileName(QWidget *parent,
// create a qt dialog
QFileDialog dialog(args);
dialog.setAcceptMode(AcceptSave);
if (selectedFilter)
if (selectedFilter && !selectedFilter->isEmpty())
dialog.selectNameFilter(*selectedFilter);
if (dialog.exec() == QDialog::Accepted) {
if (selectedFilter)

View File

@ -130,7 +130,9 @@ private slots:
void selectFilter();
void viewMode();
void proxymodel();
void setNameFilter_data();
void setNameFilter();
void setEmptyNameFilter();
void focus();
void caption();
void historyBack();
@ -1003,13 +1005,56 @@ void tst_QFiledialog::proxymodel()
QCOMPARE(fd.proxyModel(), (QAbstractProxyModel*)0);
}
void tst_QFiledialog::setNameFilter()
void tst_QFiledialog::setEmptyNameFilter()
{
QNonNativeFileDialog fd;
fd.setNameFilter(QString());
fd.setNameFilters(QStringList());
}
void tst_QFiledialog::setNameFilter_data()
{
QTest::addColumn<bool>("nameFilterDetailsVisible");
QTest::addColumn<QStringList>("filters");
QTest::addColumn<QString>("selectFilter");
QTest::addColumn<QString>("expectedSelectedFilter");
QTest::newRow("namedetailsvisible-empty") << true << QStringList() << QString() << QString();
QTest::newRow("namedetailsinvisible-empty") << false << QStringList() << QString() << QString();
const QString anyFileNoDetails = QLatin1String("Any files");
const QString anyFile = anyFileNoDetails + QLatin1String(" (*)");
const QString imageFilesNoDetails = QLatin1String("Image files");
const QString imageFiles = imageFilesNoDetails + QLatin1String(" (*.png *.xpm *.jpg)");
const QString textFileNoDetails = QLatin1String("Text files");
const QString textFile = textFileNoDetails + QLatin1String(" (*.txt)");
QStringList filters;
filters << anyFile << imageFiles << textFile;
QTest::newRow("namedetailsvisible-images") << true << filters << imageFiles << imageFiles;
QTest::newRow("namedetailsinvisible-images") << false << filters << imageFiles << imageFilesNoDetails;
const QString invalid = "foo";
QTest::newRow("namedetailsvisible-invalid") << true << filters << invalid << anyFile;
// Potential crash when trying to convert the invalid filter into a list and stripping it, resulting in an empty list.
QTest::newRow("namedetailsinvisible-invalid") << false << filters << invalid << anyFileNoDetails;
}
void tst_QFiledialog::setNameFilter()
{
QFETCH(bool, nameFilterDetailsVisible);
QFETCH(QStringList, filters);
QFETCH(QString, selectFilter);
QFETCH(QString, expectedSelectedFilter);
QNonNativeFileDialog fd;
fd.setNameFilters(filters);
fd.setNameFilterDetailsVisible(nameFilterDetailsVisible);
fd.selectNameFilter(selectFilter);
QCOMPARE(fd.selectedNameFilter(), expectedSelectedFilter);
}
void tst_QFiledialog::focus()
{
QNonNativeFileDialog fd;