From 257927c51b08242aa5bf239346717fc817b2b286 Mon Sep 17 00:00:00 2001 From: Giovanni Mascellani Date: Fri, 4 Feb 2022 10:49:25 +0100 Subject: [PATCH] xcb_io: Allow jumps backwards when widening the request number. Request numbers are not always seen in the numeric order by widen(), for example due to Mesa directly calling _XError(). When this happens, widen() adds 2^32 to the reported widened number, triggering failed assertions and bad behavior. With this commit, wrapping of the lower dword is detected in a more robust way, by requiring that a skip of at least 2^31 is seen. This fixes issue #152. Signed-off-by: Giovanni Mascellani --- src/xcb_io.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/xcb_io.c b/src/xcb_io.c index dff441ff..d800a8e1 100644 --- a/src/xcb_io.c +++ b/src/xcb_io.c @@ -214,7 +214,12 @@ static int handle_error(Display *dpy, xError *err, Bool in_XReply) static void widen(uint64_t *wide, unsigned int narrow) { uint64_t new = (*wide & ~((uint64_t)0xFFFFFFFFUL)) | narrow; - *wide = new + (((uint64_t)(new < *wide)) << 32); + /* If just copying the upper dword of *wide makes the number + * go down by more than 2^31, then it means that the lower + * dword has wrapped (or we have skipped 2^31 requests, which + * is hopefully improbable), so we add a carry. */ + uint64_t wraps = new + (1UL << 31) < *wide; + *wide = new + (wraps << 32); } /* Thread-safety rules: -- GitLab