From a3759f323a476deee8347ac3b88df1b426d7cc1a Mon Sep 17 00:00:00 2001
From: Olivier Fourdan <ofourdan@redhat.com>
Date: Thu, 21 Jan 2016 11:54:19 +0100
Subject: XKB: fix XkbGetKeyboardByName with Xming server

XkbGetKeyboardByName relies on flags to read the data from the server.

If the X server sends us the wrong flags or if a subreply is smaller
than it should be, XkbGetKeyboardByName will not read all the available
data and leave data in the buffer, which will cause the next _XReply()
to fail with:

[xcb] Extra reply data still left in queue
[xcb] This is most likely caused by a broken X extension library
[xcb] Aborting, sorry about that.
xcb_io.c:576: _XReply: Assertion `!xcb_xlib_extra_reply_data_left' failed.
Aborted

Check if there is some extra data left at the end of
XkbGetKeyboardByName() and discard that data if any is found.

Many thanks to Peter Hutterer <peter.hutterer@who-t.net> for finding the
root cause of the issue and Adam Jackson <ajax@redhat.com> for helping
with the analysis!

Signed-off-by: Olivier Fourdan <ofourdan@redhat.com>
Reviewed-by: Daniel Stone <daniels@collabora.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Backported-to-NX-by: Ulrich Sibiller <uli42@gmx.de>
---
 nx-X11/lib/X11/XKBGetByName.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

(limited to 'nx-X11/lib/X11')

diff --git a/nx-X11/lib/X11/XKBGetByName.c b/nx-X11/lib/X11/XKBGetByName.c
index 4a6ca9392..c673781ed 100644
--- a/nx-X11/lib/X11/XKBGetByName.c
+++ b/nx-X11/lib/X11/XKBGetByName.c
@@ -44,7 +44,7 @@ XkbGetKeyboardByName(Display *dpy,
 {
     register xkbGetKbdByNameReq *req;
     xkbGetKbdByNameReply rep;
-    int len, extraLen;
+    int len, extraLen = 0;
     char *str;
     XkbDescPtr xkb;
     int mapLen, codesLen, typesLen, compatLen;
@@ -204,12 +204,16 @@ XkbGetKeyboardByName(Display *dpy,
         if (status != Success)
             goto BAILOUT;
     }
+    if (extraLen > 0)
+        goto BAILOUT;
     UnlockDisplay(dpy);
     SyncHandle();
     return xkb;
  BAILOUT:
     if (xkb != NULL)
         XkbFreeKeyboard(xkb, XkbAllComponentsMask, xTrue);
+    if (extraLen > 0)
+        _XEatData(dpy, extraLen);
     UnlockDisplay(dpy);
     SyncHandle();
     return NULL;
-- 
cgit v1.2.3