[server] Don't destroy BlurInterface when parent SurfaceInterface is destroyed
Summary: Destroying the BlurInterface 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 BlurInterface it could result in heap-use-after-free. So just don't do anything, the client needs to cleanup which will result in the BlurInterface being deleted. Reviewers: #plasma Subscribers: plasma-devel Tags: #plasma Differential Revision: https://phabricator.kde.org/D1708
This commit is contained in:
parent
08bc189f8d
commit
3f1db0cfde
2 changed files with 34 additions and 8 deletions
|
@ -44,6 +44,7 @@ private Q_SLOTS:
|
||||||
void cleanup();
|
void cleanup();
|
||||||
|
|
||||||
void testCreate();
|
void testCreate();
|
||||||
|
void testSurfaceDestroy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KWayland::Server::Display *m_display;
|
KWayland::Server::Display *m_display;
|
||||||
|
@ -177,5 +178,38 @@ void TestBlur::testCreate()
|
||||||
QVERIFY(destroyedSpy.wait());
|
QVERIFY(destroyedSpy.wait());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestBlur::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 blurChanged(serverSurface, &KWayland::Server::SurfaceInterface::blurChanged);
|
||||||
|
QVERIFY(blurChanged.isValid());
|
||||||
|
|
||||||
|
QScopedPointer<KWayland::Client::Blur> blur(m_blurManager->createBlur(surface.data()));
|
||||||
|
blur->setRegion(m_compositor->createRegion(QRegion(0, 0, 10, 20), nullptr));
|
||||||
|
blur->commit();
|
||||||
|
surface->commit(KWayland::Client::Surface::CommitFlag::None);
|
||||||
|
|
||||||
|
QVERIFY(blurChanged.wait());
|
||||||
|
QCOMPARE(serverSurface->blur()->region(), QRegion(0, 0, 10, 20));
|
||||||
|
|
||||||
|
// destroy the parent surface
|
||||||
|
QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
|
||||||
|
QVERIFY(surfaceDestroyedSpy.isValid());
|
||||||
|
QSignalSpy blurDestroyedSpy(serverSurface->blur(), &QObject::destroyed);
|
||||||
|
QVERIFY(blurDestroyedSpy.isValid());
|
||||||
|
surface.reset();
|
||||||
|
QVERIFY(surfaceDestroyedSpy.wait());
|
||||||
|
QVERIFY(blurDestroyedSpy.isEmpty());
|
||||||
|
// destroy the blur
|
||||||
|
blur.reset();
|
||||||
|
QVERIFY(blurDestroyedSpy.wait());
|
||||||
|
}
|
||||||
|
|
||||||
QTEST_GUILESS_MAIN(TestBlur)
|
QTEST_GUILESS_MAIN(TestBlur)
|
||||||
#include "test_wayland_blur.moc"
|
#include "test_wayland_blur.moc"
|
||||||
|
|
|
@ -106,14 +106,6 @@ void BlurManagerInterface::Private::createBlur(wl_client *client, wl_resource *r
|
||||||
delete blur;
|
delete blur;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
QObject::connect(s, &QObject::destroyed, blur,
|
|
||||||
[blur] {
|
|
||||||
if (blur->resource()) {
|
|
||||||
wl_resource_destroy(blur->resource());
|
|
||||||
delete blur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
s->d_func()->setBlur(QPointer<BlurInterface>(blur));
|
s->d_func()->setBlur(QPointer<BlurInterface>(blur));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue