summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoman Kapl <code@rkapl.cz>2018-06-07 03:31:41 +0200
committerPeter Hutterer <peter.hutterer@who-t.net>2018-06-08 11:01:43 +1000
commitcefbc6a9356e5c6cf935b61557efa897762defae (patch)
tree814e825487120683b368002c61edb942b938c300
parent9b8999411033c9473cd68e92e4690a91aecf5b95 (diff)
Xi: fix byte-swapping of button labels
The byte-swapping code forgot that the xXIButtonInfo is followed by a button mask, not directly by the button labels. This resulted in client crashes in cross-endian setups, for example in `xinput list --long`, since the client got an invalid atom. A new function was introduced to get the right positions for the label and mask data. Signed-off-by: Roman Kapl <code@rkapl.cz> Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
-rw-r--r--Xi/xiquerydevice.c26
1 files changed, 20 insertions, 6 deletions
diff --git a/Xi/xiquerydevice.c b/Xi/xiquerydevice.c
index c0000f909..5f5a5f82f 100644
--- a/Xi/xiquerydevice.c
+++ b/Xi/xiquerydevice.c
@@ -238,6 +238,18 @@ SizeDeviceClasses(DeviceIntPtr dev)
}
/**
+ * Get pointers to button information areas holding button mask and labels.
+ */
+static void
+ButtonInfoData(xXIButtonInfo *info, int *mask_words, unsigned char **mask,
+ Atom **atoms)
+{
+ *mask_words = bytes_to_int32(bits_to_bytes(info->num_buttons));
+ *mask = (unsigned char*) &info[1];
+ *atoms = (Atom*) ((*mask) + (*mask_words) * 4);
+}
+
+/**
* Write button information into info.
* @return Number of bytes written into info.
*/
@@ -245,21 +257,20 @@ int
ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
{
unsigned char *bits;
+ Atom *labels;
int mask_len;
int i;
if (!dev || !dev->button)
return 0;
- mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons));
-
info->type = ButtonClass;
info->num_buttons = dev->button->numButtons;
+ ButtonInfoData(info, &mask_len, &bits, &labels);
info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
info->num_buttons + mask_len;
info->sourceid = dev->button->sourceid;
- bits = (unsigned char *) &info[1];
memset(bits, 0, mask_len * 4);
if (reportState)
@@ -267,8 +278,7 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
if (BitIsOn(dev->button->down, i))
SetBit(bits, i);
- bits += mask_len * 4;
- memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom));
+ memcpy(labels, dev->button->labels, dev->button->numButtons * sizeof(Atom));
return info->length * 4;
}
@@ -277,13 +287,17 @@ static void
SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info)
{
Atom *btn;
+ int mask_len;
+ unsigned char *mask;
+
int i;
+ ButtonInfoData(info, &mask_len, &mask, &btn);
swaps(&info->type);
swaps(&info->length);
swaps(&info->sourceid);
- for (i = 0, btn = (Atom *) &info[1]; i < info->num_buttons; i++, btn++)
+ for (i = 0 ; i < info->num_buttons; i++, btn++)
swapl(btn);
swaps(&info->num_buttons);