Fix memory leak in QClipboard::setMimeData()

The setMimeData() function is documented to take ownership of
the object passed in, but in the case where the platform
plugin did not support the requested mode, we would simply
return without deleting the object nor telling the application,
so it would cause a potential memory leak. We need to honor the
contract, even when we fail to set the mime data.

Test was updated to avoid verifying the leak in cases where
the platform does not support all modes.

[ChangeLog][QtGui][Clipboard] Fixed a memory leak in setMimeData()
when the platform plugin did not support the requested mode.

Task-number: QTBUG-41852
Change-Id: I2112da1613199fe1b56724e7ccf097b9e912c117
Reviewed-by: Richard Moe Gustavsen <richard.gustavsen@digia.com>
This commit is contained in:
Eskil Abrahamsen Blomfeldt 2014-10-09 12:46:04 +02:00
parent 9685c72e37
commit 74a20b77a6
2 changed files with 20 additions and 9 deletions

View File

@ -463,9 +463,14 @@ const QMimeData* QClipboard::mimeData(Mode mode) const
void QClipboard::setMimeData(QMimeData* src, Mode mode)
{
QPlatformClipboard *clipboard = QGuiApplicationPrivate::platformIntegration()->clipboard();
if (!clipboard->supportsMode(mode)) return;
clipboard->setMimeData(src,mode);
if (!clipboard->supportsMode(mode)) {
if (src != 0) {
qWarning("Data set on unsupported clipboard mode. QMimeData object will be deleted.");
src->deleteLater();
}
} else {
clipboard->setMimeData(src,mode);
}
}
/*!

View File

@ -340,8 +340,10 @@ void tst_QClipboard::setMimeData()
data->setText("foo");
QGuiApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection);
QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer);
if (QGuiApplication::clipboard()->supportsSelection())
QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection);
if (QGuiApplication::clipboard()->supportsFindBuffer())
QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer);
QSignalSpy spySelection(QGuiApplication::clipboard(), SIGNAL(selectionChanged()));
QSignalSpy spyData(QGuiApplication::clipboard(), SIGNAL(dataChanged()));
@ -373,8 +375,10 @@ void tst_QClipboard::setMimeData()
data->setText("foo");
QGuiApplication::clipboard()->setMimeData(data, QClipboard::Clipboard);
QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection);
QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer);
if (QGuiApplication::clipboard()->supportsSelection())
QGuiApplication::clipboard()->setMimeData(data, QClipboard::Selection);
if (QGuiApplication::clipboard()->supportsFindBuffer())
QGuiApplication::clipboard()->setMimeData(data, QClipboard::FindBuffer);
QMimeData *newData = new QMimeData;
newData->setText("bar");
@ -385,8 +389,10 @@ void tst_QClipboard::setMimeData()
spyFindBuffer.clear();
QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Clipboard);
QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Selection); // used to crash on X11
QGuiApplication::clipboard()->setMimeData(newData, QClipboard::FindBuffer);
if (QGuiApplication::clipboard()->supportsSelection())
QGuiApplication::clipboard()->setMimeData(newData, QClipboard::Selection); // used to crash on X11
if (QGuiApplication::clipboard()->supportsFindBuffer())
QGuiApplication::clipboard()->setMimeData(newData, QClipboard::FindBuffer);
if (QGuiApplication::clipboard()->supportsSelection())
QCOMPARE(spySelection.count(), 1);