Don't report results when the results list is empty

When inserting items into the result store, a ResultItem is created,
which stores a pointer to the results list and their size. If the size
of the ResultItem is set to 0, it means that a single result is stored.
In case of trying to report results via an empty list, the size is 0, so
result store treats it as a single result.

Added checks before storing the results to make sure that the result
list isn't empty. Note that empty lists are allowed in some cases for
the filter mode, because ResultStoreBase::addResults() knows how to
handle those cases correctly.

Task-number: QTBUG-80957
Pick-to: 5.15 6.1 6.2
Change-Id: I399af4c3eef6adf82fea5df031fe9a9075006b1f
Reviewed-by: Mårten Nordheim <marten.nordheim@qt.io>
This commit is contained in:
Sona Kurazyan 2021-07-26 17:03:37 +02:00
parent 3b8127c3fc
commit 08de1fb281
4 changed files with 44 additions and 0 deletions

View File

@ -235,6 +235,7 @@ int ResultStoreBase::addResult(int index, const void *result)
int ResultStoreBase::addResults(int index, const void *results, int vectorSize, int totalCount)
{
if (m_filterMode == false || vectorSize == totalCount) {
Q_ASSERT(vectorSize != 0);
ResultItem resultItem(results, vectorSize);
return insertResultItem(index, resultItem);
} else {

View File

@ -194,6 +194,9 @@ public:
template<typename T>
int addResults(int index, const QList<T> *results)
{
if (results->empty()) // reject if results are empty
return -1;
if (containsValidResultItem(index)) // reject if already present
return -1;
@ -203,6 +206,10 @@ public:
template<typename T>
int addResults(int index, const QList<T> *results, int totalCount)
{
// reject if results are empty, and nothing is filtered away
if ((m_filterMode == false || results->count() == totalCount) && results->empty())
return -1;
if (containsValidResultItem(index)) // reject if already present
return -1;

View File

@ -733,6 +733,26 @@ void tst_QFuture::futureInterface()
QCOMPARE(i1.resultReference(0), 2);
QCOMPARE(i2.resultReference(0), 1);
}
{
QFutureInterface<int> fi;
fi.reportStarted();
QVERIFY(!fi.reportResults(QList<int> {}));
fi.reportFinished();
QVERIFY(fi.results().empty());
}
{
QFutureInterface<int> fi;
fi.reportStarted();
QList<int> values = { 1, 2, 3 };
QVERIFY(fi.reportResults(values));
QVERIFY(!fi.reportResults(QList<int> {}));
fi.reportFinished();
QCOMPARE(fi.results(), values);
}
}
template <typename T>

View File

@ -177,6 +177,14 @@ void tst_QtConcurrentResultStore::addResults()
++it;
QCOMPARE(it, store.end());
QList<int> empty;
const auto countBefore = store.count();
QCOMPARE(store.addResults(countBefore, &empty), -1);
QCOMPARE(store.count(), countBefore);
QCOMPARE(store.addResults(countBefore, &vec1), countBefore);
QCOMPARE(store.count(), countBefore + vec1.size());
}
void tst_QtConcurrentResultStore::resultIndex()
@ -340,6 +348,14 @@ void tst_QtConcurrentResultStore::filterMode()
QCOMPARE(store.contains(6), true);
QCOMPARE(store.contains(7), true);
QCOMPARE(store.contains(8), false);
QList<int> empty;
const auto countBefore = store.count();
QCOMPARE(store.addResults(countBefore, &empty), -1);
QCOMPARE(store.count(), countBefore);
QCOMPARE(store.addResult(countBefore, &int2), countBefore);
QCOMPARE(store.count(), countBefore + 1);
}
void tst_QtConcurrentResultStore::addCanceledResult()