summaryrefslogtreecommitdiffstats
path: root/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
diff options
context:
space:
mode:
authorPaul Olav Tvete <paul.tvete@qt.io>2020-12-23 13:18:04 +0100
committerPaul Olav Tvete <paul.tvete@qt.io>2020-12-23 15:25:02 +0100
commitc80d6473fbeb43074fb63db66e162e76cb2bf3ef (patch)
tree23703fe65d69a19fc05c3c6209cafad654929f2c /src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
parent3729d37dd9ad38044242097adaa4bd74e2d5de87 (diff)
Fix out-of-bounds write
Change ac210c73e4 introduced the requirement that all input devices with Scroll capability must have a QXcbScrollingDevicePrivate as their d_ptr. However, this was not enforced, and would fail for the "Virtual core pointer". To fix this, always use qobject_cast to verify that the device is of the correct type. Change-Id: I4a6b1d4d79308eb04e9f52dda00294fffe377bdf Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
Diffstat (limited to 'src/plugins/platforms/xcb/qxcbconnection_xi2.cpp')
-rw-r--r--src/plugins/platforms/xcb/qxcbconnection_xi2.cpp30
1 files changed, 16 insertions, 14 deletions
diff --git a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
index 03c45dfc3e..04d2c57e9e 100644
--- a/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
+++ b/src/plugins/platforms/xcb/qxcbconnection_xi2.cpp
@@ -433,7 +433,7 @@ void QXcbConnection::xi2SetupSlavePointerDevice(void *info, bool removeExisting,
scrollingDeviceP->buttonCount = buttonCount;
if (master)
scrollingDeviceP->seatName = master->seatName();
- QWindowSystemInterface::registerInputDevice(new QXcbScrollingMouse(*scrollingDeviceP, master));
+ QWindowSystemInterface::registerInputDevice(new QXcbScrollingDevice(*scrollingDeviceP, master));
} else {
QWindowSystemInterface::registerInputDevice(new QPointingDevice(
name, deviceInfo->deviceid,
@@ -991,8 +991,13 @@ void QXcbConnection::xi2HandleDeviceChangedEvent(void *event)
}
}
-void QXcbConnection::xi2UpdateScrollingDevice(QXcbScrollingDevicePrivate *scrollingDevice)
+void QXcbConnection::xi2UpdateScrollingDevice(QInputDevice *dev)
{
+ QXcbScrollingDevice *scrollDev = qobject_cast<QXcbScrollingDevice *>(dev);
+ if (!scrollDev || !scrollDev->capabilities().testFlag(QInputDevice::Capability::Scroll))
+ return;
+ QXcbScrollingDevicePrivate *scrollingDevice = QXcbScrollingDevice::get(scrollDev);
+
auto reply = Q_XCB_REPLY(xcb_input_xi_query_device, xcb_connection(), scrollingDevice->systemId);
if (!reply || reply->num_infos <= 0) {
qCDebug(lcQpaXInputDevices, "scrolling device %lld no longer present", scrollingDevice->systemId);
@@ -1026,30 +1031,27 @@ void QXcbConnection::xi2UpdateScrollingDevices()
{
const auto &devices = QInputDevice::devices();
for (const QInputDevice *dev : devices) {
- if (dev->capabilities().testFlag(QInputDevice::Capability::Scroll)) {
- const auto devPriv = QPointingDevicePrivate::get(static_cast<QPointingDevice *>(const_cast<QInputDevice *>(dev)));
- xi2UpdateScrollingDevice(static_cast<QXcbScrollingDevicePrivate *>(devPriv));
- }
+ if (dev->capabilities().testFlag(QInputDevice::Capability::Scroll))
+ xi2UpdateScrollingDevice(const_cast<QInputDevice *>(dev));
}
}
-QXcbScrollingDevicePrivate *QXcbConnection::scrollingDeviceForId(int id)
+QXcbScrollingDevice *QXcbConnection::scrollingDeviceForId(int id)
{
const QPointingDevice *dev = QPointingDevicePrivate::pointingDeviceById(id);
- if (!dev)
+ if (!dev|| !dev->capabilities().testFlag(QInputDevice::Capability::Scroll))
return nullptr;
- if (!dev->capabilities().testFlag(QInputDevice::Capability::Scroll))
- return nullptr;
- auto devPriv = QPointingDevicePrivate::get(const_cast<QPointingDevice *>(dev));
- return static_cast<QXcbScrollingDevicePrivate *>(devPriv);
+ return qobject_cast<QXcbScrollingDevice *>(const_cast<QPointingDevice *>(dev));
}
void QXcbConnection::xi2HandleScrollEvent(void *event, const QPointingDevice *dev)
{
auto *xiDeviceEvent = reinterpret_cast<qt_xcb_input_device_event_t *>(event);
- if (!dev->capabilities().testFlag(QInputDevice::Capability::Scroll))
+
+ const QXcbScrollingDevice *scrollDev = qobject_cast<const QXcbScrollingDevice *>(dev);
+ if (!scrollDev || !scrollDev->capabilities().testFlag(QInputDevice::Capability::Scroll))
return;
- const auto scrollingDevice = static_cast<const QXcbScrollingDevicePrivate *>(QPointingDevicePrivate::get(dev));
+ const QXcbScrollingDevicePrivate *scrollingDevice = QXcbScrollingDevice::get(scrollDev);
if (xiDeviceEvent->event_type == XCB_INPUT_MOTION && scrollingDevice->orientations) {
if (QXcbWindow *platformWindow = platformWindowFromId(xiDeviceEvent->event)) {