[server] Don't destroy ContrastInterface when parent SurfaceInterface is destroyed
Summary: Destroying the ContrastInterface on the server side before the client has a chance to cleanup results in a protocol error: wl_display@1: error 0: invalid object 7 Which would terminate the client. If we would not destroy the resource, but only delete the ContrastInterface it could result in heap-use-after-free. So just don't do anything, the client needs to cleanup which will result in the ContrastInterface being deleted. Reviewers: #plasma Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D1709
This commit is contained in:
parent
3f1db0cfde
commit
5232dc5f0f
2 changed files with 34 additions and 8 deletions
|
@ -47,6 +47,7 @@ private Q_SLOTS:
|
|||
void cleanup();
|
||||
|
||||
void testCreate();
|
||||
void testSurfaceDestroy();
|
||||
|
||||
private:
|
||||
KWayland::Server::Display *m_display;
|
||||
|
@ -187,5 +188,38 @@ void TestContrast::testCreate()
|
|||
QVERIFY(destroyedSpy.wait());
|
||||
}
|
||||
|
||||
void TestContrast::testSurfaceDestroy()
|
||||
{
|
||||
QSignalSpy serverSurfaceCreated(m_compositorInterface, &KWayland::Server::CompositorInterface::surfaceCreated);
|
||||
QVERIFY(serverSurfaceCreated.isValid());
|
||||
|
||||
QScopedPointer<KWayland::Client::Surface> surface(m_compositor->createSurface());
|
||||
QVERIFY(serverSurfaceCreated.wait());
|
||||
|
||||
auto serverSurface = serverSurfaceCreated.first().first().value<KWayland::Server::SurfaceInterface*>();
|
||||
QSignalSpy contrastChanged(serverSurface, &KWayland::Server::SurfaceInterface::contrastChanged);
|
||||
QVERIFY(contrastChanged.isValid());
|
||||
|
||||
QScopedPointer<KWayland::Client::Contrast> contrast(m_contrastManager->createContrast(surface.data()));
|
||||
contrast->setRegion(m_compositor->createRegion(QRegion(0, 0, 10, 20), nullptr));
|
||||
contrast->commit();
|
||||
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||
|
||||
QVERIFY(contrastChanged.wait());
|
||||
QCOMPARE(serverSurface->contrast()->region(), QRegion(0, 0, 10, 20));
|
||||
|
||||
// destroy the parent surface
|
||||
QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
|
||||
QVERIFY(surfaceDestroyedSpy.isValid());
|
||||
QSignalSpy contrastDestroyedSpy(serverSurface->contrast(), &QObject::destroyed);
|
||||
QVERIFY(contrastDestroyedSpy.isValid());
|
||||
surface.reset();
|
||||
QVERIFY(surfaceDestroyedSpy.wait());
|
||||
QVERIFY(contrastDestroyedSpy.isEmpty());
|
||||
// destroy the blur
|
||||
contrast.reset();
|
||||
QVERIFY(contrastDestroyedSpy.wait());
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(TestContrast)
|
||||
#include "test_wayland_contrast.moc"
|
||||
|
|
|
@ -106,14 +106,6 @@ void ContrastManagerInterface::Private::createContrast(wl_client *client, wl_res
|
|||
delete contrast;
|
||||
return;
|
||||
}
|
||||
QObject::connect(s, &QObject::destroyed, contrast,
|
||||
[contrast] {
|
||||
if (contrast->resource()) {
|
||||
wl_resource_destroy(contrast->resource());
|
||||
delete contrast;
|
||||
}
|
||||
}
|
||||
);
|
||||
s->d_func()->setContrast(QPointer<ContrastInterface>(contrast));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue