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>
This commit is contained in:
parent
9b89994110
commit
cefbc6a935
|
@ -237,6 +237,18 @@ SizeDeviceClasses(DeviceIntPtr dev)
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
* Write button information into info.
|
||||||
* @return Number of bytes written into info.
|
* @return Number of bytes written into info.
|
||||||
|
@ -245,21 +257,20 @@ int
|
||||||
ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
|
ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
|
||||||
{
|
{
|
||||||
unsigned char *bits;
|
unsigned char *bits;
|
||||||
|
Atom *labels;
|
||||||
int mask_len;
|
int mask_len;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (!dev || !dev->button)
|
if (!dev || !dev->button)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons));
|
|
||||||
|
|
||||||
info->type = ButtonClass;
|
info->type = ButtonClass;
|
||||||
info->num_buttons = dev->button->numButtons;
|
info->num_buttons = dev->button->numButtons;
|
||||||
|
ButtonInfoData(info, &mask_len, &bits, &labels);
|
||||||
info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
|
info->length = bytes_to_int32(sizeof(xXIButtonInfo)) +
|
||||||
info->num_buttons + mask_len;
|
info->num_buttons + mask_len;
|
||||||
info->sourceid = dev->button->sourceid;
|
info->sourceid = dev->button->sourceid;
|
||||||
|
|
||||||
bits = (unsigned char *) &info[1];
|
|
||||||
memset(bits, 0, mask_len * 4);
|
memset(bits, 0, mask_len * 4);
|
||||||
|
|
||||||
if (reportState)
|
if (reportState)
|
||||||
|
@ -267,8 +278,7 @@ ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState)
|
||||||
if (BitIsOn(dev->button->down, i))
|
if (BitIsOn(dev->button->down, i))
|
||||||
SetBit(bits, i);
|
SetBit(bits, i);
|
||||||
|
|
||||||
bits += mask_len * 4;
|
memcpy(labels, dev->button->labels, dev->button->numButtons * sizeof(Atom));
|
||||||
memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom));
|
|
||||||
|
|
||||||
return info->length * 4;
|
return info->length * 4;
|
||||||
}
|
}
|
||||||
|
@ -277,13 +287,17 @@ static void
|
||||||
SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info)
|
SwapButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info)
|
||||||
{
|
{
|
||||||
Atom *btn;
|
Atom *btn;
|
||||||
|
int mask_len;
|
||||||
|
unsigned char *mask;
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
ButtonInfoData(info, &mask_len, &mask, &btn);
|
||||||
|
|
||||||
swaps(&info->type);
|
swaps(&info->type);
|
||||||
swaps(&info->length);
|
swaps(&info->length);
|
||||||
swaps(&info->sourceid);
|
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);
|
swapl(btn);
|
||||||
|
|
||||||
swaps(&info->num_buttons);
|
swaps(&info->num_buttons);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user