Xext/saver: Swap ScreenSaverSuspend 'suspend' field. Handle old XCB clients.

This field was defined as a Bool in the protocol headers and BOOL in
xcb. Bool is not a valid type for protocol fields. It is defined as
'int' by Xdefs.h, which we expect to be 32-bits on all machines.

The protocol headers and xcb have patches posted to switch to CARD32,
which is at least well defined.

This change adds the necessary byte swapping to handle other-endian
clients with this 32-bit field, and then changes the request
processing to compare all 32-bits against zero so that it works with
both new and old clients.

On MSB machines, Xlib will continue to work properly, but old XCB will
not interoperate with the X server (either before or after this patch).

Signed-off-by: Keith Packard <keithp@keithp.com>
Reviewed-by: Mihai Moldovan <ionic@ionic.de>
Reviewed-by: Adam Jackson <ajax@redhat.com>
This commit is contained in:
Keith Packard 2018-03-12 12:14:44 -07:00
parent beda6afb3c
commit 52048ce29f
1 changed files with 12 additions and 2 deletions

View File

@ -1209,17 +1209,26 @@ static int
ProcScreenSaverSuspend(ClientPtr client)
{
ScreenSaverSuspensionPtr *prev, this;
BOOL suspend;
REQUEST(xScreenSaverSuspendReq);
REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
/*
* Old versions of XCB encode suspend as 1 byte followed by three
* pad bytes (which are always cleared), instead of a 4 byte
* value. Be compatible by just checking for a non-zero value in
* all 32-bits.
*/
suspend = stuff->suspend != 0;
/* Check if this client is suspending the screensaver */
for (prev = &suspendingClients; (this = *prev); prev = &this->next)
if (this->pClient == client)
break;
if (this) {
if (stuff->suspend == TRUE)
if (suspend == TRUE)
this->count++;
else if (--this->count == 0)
FreeResource(this->clientResource, RT_NONE);
@ -1228,7 +1237,7 @@ ProcScreenSaverSuspend(ClientPtr client)
}
/* If we get to this point, this client isn't suspending the screensaver */
if (stuff->suspend == FALSE)
if (suspend == FALSE)
return Success;
/*
@ -1342,6 +1351,7 @@ SProcScreenSaverSuspend(ClientPtr client)
REQUEST(xScreenSaverSuspendReq);
swaps(&stuff->length);
swapl(&stuff->suspend);
REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
return ProcScreenSaverSuspend(client);
}