client/X11: Avoid crash in XGetDeviceButtonMapping()

XOpenDevice() may fail and return NULL, so try to find the first
pointer device that can be opened, and ensure that ptr_dev argument
is not NULL before passing it to XGetDeviceButtonMapping().
This commit is contained in:
Alexander Volkov 2020-01-15 14:32:08 +03:00 committed by akallabeth
parent 30d6e25def
commit f0321a049d
1 changed files with 9 additions and 9 deletions

View File

@ -979,7 +979,6 @@ static void xf_get_x11_button_map(xfContext* xfc, unsigned char* x11_map)
{
#ifdef WITH_XI
int opcode, event, error;
int xid;
XDevice* ptr_dev;
XExtensionVersion* version;
XDeviceInfo* devices1;
@ -989,7 +988,7 @@ static void xf_get_x11_button_map(xfContext* xfc, unsigned char* x11_map)
if (XQueryExtension(xfc->display, "XInputExtension", &opcode, &event, &error))
{
WLog_DBG(TAG, "Searching for XInput pointer device");
xid = INVALID_XID;
ptr_dev = NULL;
/* loop through every device, looking for a pointer */
version = XGetExtensionVersion(xfc->display, INAME);
@ -1005,8 +1004,9 @@ static void xf_get_x11_button_map(xfContext* xfc, unsigned char* x11_map)
if ((devices2[i].use == XISlavePointer) &&
(strncmp(devices2[i].name, TEST_PTR_STR, TEST_PTR_LEN) != 0))
{
xid = devices2[i].deviceid;
break;
ptr_dev = XOpenDevice(xfc->display, devices2[i].deviceid);
if (ptr_dev)
break;
}
}
@ -1025,8 +1025,9 @@ static void xf_get_x11_button_map(xfContext* xfc, unsigned char* x11_map)
if ((devices1[i].use == IsXExtensionPointer) &&
(strncmp(devices1[i].name, TEST_PTR_STR, TEST_PTR_LEN) != 0))
{
xid = devices1[i].id;
break;
ptr_dev = XOpenDevice(xfc->display, devices1[i].id);
if (ptr_dev)
break;
}
}
@ -1038,10 +1039,9 @@ static void xf_get_x11_button_map(xfContext* xfc, unsigned char* x11_map)
/* get button mapping from input extension if there is a pointer device; */
/* otherwise leave unchanged. */
if (xid != INVALID_XID)
if (ptr_dev)
{
WLog_DBG(TAG, "Pointer device: %d", xid);
ptr_dev = XOpenDevice(xfc->display, xid);
WLog_DBG(TAG, "Pointer device: %d", ptr_dev->device_id);
XGetDeviceButtonMapping(xfc->display, ptr_dev, x11_map, NUM_BUTTONS_MAPPED);
XCloseDevice(xfc->display, ptr_dev);
}