Commit 0b19734d authored by Martin Flöser's avatar Martin Flöser
Browse files

[server] Don't destroy SlideInterface when parent SurfaceInterface is destroyed

Summary:
Destroying the SlideInterface 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 SlideInterface it could result in heap-use-after-free.

So just don't do anything, the client needs to cleanup which will result
in the SlideInterface being deleted.

Reviewers: #plasma

Subscribers: plasma-devel

Tags: #plasma

Differential Revision: https://phabricator.kde.org/D1714
parent 555ef7f1
......@@ -44,6 +44,7 @@ private Q_SLOTS:
void cleanup();
void testCreate();
void testSurfaceDestroy();
private:
KWayland::Server::Display *m_display;
......@@ -178,5 +179,38 @@ void TestSlide::testCreate()
QVERIFY(destroyedSpy.wait());
}
void TestSlide::testSurfaceDestroy()
{
using namespace KWayland::Server;
QSignalSpy serverSurfaceCreated(m_compositorInterface, &CompositorInterface::surfaceCreated);
QVERIFY(serverSurfaceCreated.isValid());
QScopedPointer<KWayland::Client::Surface> surface(m_compositor->createSurface());
QVERIFY(serverSurfaceCreated.wait());
auto serverSurface = serverSurfaceCreated.first().first().value<SurfaceInterface*>();
QSignalSpy slideChanged(serverSurface, &SurfaceInterface::slideOnShowHideChanged);
QVERIFY(slideChanged.isValid());
QScopedPointer<Slide> slide(m_slideManager->createSlide(surface.data()));
slide->commit();
surface->commit(KWayland::Client::Surface::CommitFlag::None);
QVERIFY(slideChanged.wait());
auto serverSlide = serverSurface->slideOnShowHide();
QVERIFY(!serverSlide.isNull());
// destroy the parent surface
QSignalSpy surfaceDestroyedSpy(serverSurface, &QObject::destroyed);
QVERIFY(surfaceDestroyedSpy.isValid());
QSignalSpy slideDestroyedSpy(serverSlide.data(), &QObject::destroyed);
QVERIFY(slideDestroyedSpy.isValid());
surface.reset();
QVERIFY(surfaceDestroyedSpy.wait());
QVERIFY(slideDestroyedSpy.isEmpty());
// destroy the slide
slide.reset();
QVERIFY(slideDestroyedSpy.wait());
}
QTEST_GUILESS_MAIN(TestSlide)
#include "test_wayland_slide.moc"
......@@ -83,14 +83,6 @@ void SlideManagerInterface::Private::createSlide(wl_client *client, wl_resource
delete slide;
return;
}
QObject::connect(s, &QObject::destroyed, slide,
[slide] {
if (slide->resource()) {
wl_resource_destroy(slide->resource());
delete slide;
}
}
);
s->d_func()->setSlide(QPointer<SlideInterface>(slide));
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment