3rdparty: Fix forwards-compatibility bug in bundled xinput xcb module

libxcb thinks that it knows about all device class types sent by the X
server XInput extension. With the addition of touchpad gestures in
XInput 2.4 and X server 21.1 this is no longer the case and libxcb fails
horribly by thinking that the protocol was malformed.

The X server currently has a workaround, but it would not address the
following situation:

- there are multiple modules within the same X client (e.g. part of the
application uses Qt, another part talks to X server via another library)
 - both of the modules talk to XI
 - at least one module requests for XI 2.4 protocol support.

The request for XI 2.4 disables the workaround on the X server and Qt
side would crash horribly.

This bug is being fixed upstream in these MRs:
https://gitlab.freedesktop.org/xorg/proto/xcbproto/-/merge_requests/23
https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/20

Change-Id: Idf345271340031152b512ef59f619313be5ec226
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Reviewed-by: Shawn Rutledge <shawn.rutledge@qt.io>
This commit is contained in:
Povilas Kanapickas 2021-09-03 16:23:06 +03:00
parent 1479f057f3
commit 2d5541d6c3
3 changed files with 63 additions and 25 deletions

View File

@ -20,3 +20,27 @@ The xcb-xinput files where modified to use system includes, see:
src/3rdparty/xcb/include/xcb/fixup-xinput-h.patch
src/3rdparty/xcb/libxcb/fixup-xinput-c.patch
*****************************************************************
Additionally, a forwards compatibility bug in libxcb xinput has been addressed
by the following patch:
src/3rdparty/xcb/libxcb/xinput-device-class-sizeof.patch
The crux of the issue is that libxcb thinks that it knows about all device
class types sent by the X server XInput extension. With the addition of
touchpad gestures in XInput 2.4 and X server 21.1 this is no longer the case
and libxcb fails horribly by thinking that the protocol was malformed.
The X server currently has a workaround, but it would not address the following
situation:
- there are multiple modules within the same X client (e.g. part of the application
uses Qt, another part talks to X server via another library)
- both of the modules talk to XI
- at least one module requests for XI 2.4 protocol support.
The request for XI 2.4 disables the workaround on the X server and Qt side would
crash horribly.
For more details, see https://gitlab.freedesktop.org/xorg/lib/libxcb/-/merge_requests/20

View File

@ -0,0 +1,38 @@
diff --git a/src/3rdparty/xcb/libxcb/xinput.c b/src/3rdparty/xcb/libxcb/xinput.c
index d4e3c250bc..5113213a61 100644
--- a/src/3rdparty/xcb/libxcb/xinput.c
+++ b/src/3rdparty/xcb/libxcb/xinput.c
@@ -10535,32 +10535,8 @@ xcb_input_device_class_data_sizeof (const void *_buffer,
int
xcb_input_device_class_sizeof (const void *_buffer)
{
- char *xcb_tmp = (char *)_buffer;
const xcb_input_device_class_t *_aux = (xcb_input_device_class_t *)_buffer;
- unsigned int xcb_buffer_len = 0;
- unsigned int xcb_block_len = 0;
- unsigned int xcb_pad = 0;
- unsigned int xcb_align_to = 0;
-
-
- xcb_block_len += sizeof(xcb_input_device_class_t);
- xcb_tmp += xcb_block_len;
- xcb_buffer_len += xcb_block_len;
- xcb_block_len = 0;
- /* data */
- xcb_block_len += xcb_input_device_class_data_sizeof(xcb_tmp, _aux->type);
- xcb_tmp += xcb_block_len;
- xcb_align_to = ALIGNOF(char);
- /* insert padding */
- xcb_pad = -xcb_block_len & (xcb_align_to - 1);
- xcb_buffer_len += xcb_block_len + xcb_pad;
- if (0 != xcb_pad) {
- xcb_tmp += xcb_pad;
- xcb_pad = 0;
- }
- xcb_block_len = 0;
-
- return xcb_buffer_len;
+ return (_aux->len * 4);
}
void *

View File

@ -10535,32 +10535,8 @@ xcb_input_device_class_data_sizeof (const void *_buffer,
int
xcb_input_device_class_sizeof (const void *_buffer)
{
char *xcb_tmp = (char *)_buffer;
const xcb_input_device_class_t *_aux = (xcb_input_device_class_t *)_buffer;
unsigned int xcb_buffer_len = 0;
unsigned int xcb_block_len = 0;
unsigned int xcb_pad = 0;
unsigned int xcb_align_to = 0;
xcb_block_len += sizeof(xcb_input_device_class_t);
xcb_tmp += xcb_block_len;
xcb_buffer_len += xcb_block_len;
xcb_block_len = 0;
/* data */
xcb_block_len += xcb_input_device_class_data_sizeof(xcb_tmp, _aux->type);
xcb_tmp += xcb_block_len;
xcb_align_to = ALIGNOF(char);
/* insert padding */
xcb_pad = -xcb_block_len & (xcb_align_to - 1);
xcb_buffer_len += xcb_block_len + xcb_pad;
if (0 != xcb_pad) {
xcb_tmp += xcb_pad;
xcb_pad = 0;
}
xcb_block_len = 0;
return xcb_buffer_len;
return (_aux->len * 4);
}
void *