Peter Hutterer wrote:
On Wed, Nov 25, 2009 at 04:42:59PM -0500, Nathan Kidd wrote:
In the last few years inputproto's number of events (IEVENTS) has jumped
around quite a bit between 15 and 19, which has resulted in the
following issue I've recently became aware of:
...
AIUI, other extensions may be affected as well, not just
Xi. Any newer library extension run against an older server (where the
extension differs in the number of events) would suffer from this issue.

Correct; XInput just got noticed because it's had more development of
late.  (The unfair rewards of all your work on Xi :) )

Attached is an attempt of a fix to libXext. There's not a lot of
wriggle-room, the APIs are quite restrictive and we can't pass a great deal
of information around. Additionally, the library has no way of knowing how
many events a given extension has, it's pure guesswork (or compiled into the
library).

The reason not to just use the display's event_vec (attached patches,
your log message reused) is to avoid adding a libX11/libXext version
dependency?

Either approach fixes the WireToEvent case when considering events being
generated by the server, but I don't think there's anything that can be
done about the EventToWire (SendEvent request) case.  Your choice is to
use the wrong EventToWire function for either the overlapping extension
events, or the following extension events.  The former is preferred I
think since it will only break very new code (using new events).

Currently two unpatched clients could SendEvent new events (that xserver
didn't know about) successfully if they query extensions in the same
order.  The patch will break them, but that's the only fallout I can
think of, and it seems necessary.

-Nathan


>From 9a723019b4cef32ac5a2f3c2e3aaadef5447f783 Mon Sep 17 00:00:00 2001
From: Nathan Kidd <nk...@opentext.com>
Date: Thu, 26 Nov 2009 12:29:10 -0500
Subject: [PATCH] Add XEGetWireToEvent()

Used by libXext to tell if an extension lib and xserver
were built with a difference in the number of extension events,
and avoid resulting protocol decoding errors.

Signed-off-by: Nathan Kidd <nk...@opentext.com>
---
 include/X11/Xlibint.h |    7 +++++++
 src/InitExt.c         |   11 +++++++++++
 2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/include/X11/Xlibint.h b/include/X11/Xlibint.h
index 2acfc76..010e12e 100644
--- a/include/X11/Xlibint.h
+++ b/include/X11/Xlibint.h
@@ -1184,6 +1184,13 @@ extern Bool (*XESetWireToEvent(
     Display*, XEvent*, xEvent*
 );
 
+extern Bool (*XEGetWireToEvent(
+    Display*		/* display */,
+    int			/* event_number */
+))(
+    Display*, XEvent*, xEvent*
+);
+
 extern Bool (*XESetWireToEventCookie(
     Display*		/* display */,
     int			/* extension */,
diff --git a/src/InitExt.c b/src/InitExt.c
index 0e6c94e..3068159 100644
--- a/src/InitExt.c
+++ b/src/InitExt.c
@@ -253,6 +253,17 @@ WireToEventType XESetWireToEvent(
 	return (WireToEventType)oldproc;
 }
 
+WireToEventType XEGetWireToEvent(
+	Display *dpy,		/* display */
+	int event_number)	/* event routine to get */
+{
+	register WireToEventType proc;
+	LockDisplay (dpy);
+	proc = dpy->event_vec[event_number];
+	UnlockDisplay (dpy);
+	return (WireToEventType)proc;
+}
+
 typedef Bool (*WireToEventCookieType) (
     Display*	/* display */,
     XGenericEventCookie*	/* re */,
-- 
1.6.0.4



>From f0bf7e955509afe8124925e9f930522df3babc5e Mon Sep 17 00:00:00 2001
From: Nathan Kidd <nk...@opentext.com>
Date: Thu, 26 Nov 2009 11:54:36 -0500
Subject: [PATCH] Don't smash the event_vec if num_events differs between lib and server.

If the library extension thinks there's more events to an extension than the
server actually has, the event_vec for the overlapping range can get
overwritten. This depends on the initialization order of the libraries.

Signed-off-by: Nathan Kidd <nk...@opentext.com>
---
 src/extutil.c |   20 ++++++++++++++++++++
 1 files changed, 20 insertions(+), 0 deletions(-)

diff --git a/src/extutil.c b/src/extutil.c
index ac861ea..a1a42f6 100644
--- a/src/extutil.c
+++ b/src/extutil.c
@@ -119,6 +119,26 @@ XExtDisplayInfo *XextAddDisplay (
 	int i, j;
 
 	for (i = 0, j = dpyinfo->codes->first_event; i < nevents; i++, j++) {
+            /*
+             * Xlib initializes all event vectors to unknown. If the
+             * vector is not unknown it means we would overwrite another
+             * extension's vector.  This can happen when the extension lib
+             * is built with more events than the xserver was built with,
+             * so the xserver's space between event_bases is smaller than
+             * the lib expects.
+             *
+             * For receiving events it is safe to simply not set these extra
+             * event vectors since the xserver doesn't know about these
+             * events and thus will never send them.
+             *
+             * For sending events, we can't avoid using the wrong EventToWire
+             * function; either for the (typically) few overlapping events in
+             * this extension or else for the first overlapped events in the
+             * next (event-base-wise) extension.  Prefer the former.
+             */
+	    if (XEGetWireToEvent (dpy, j) != _XUnknownWireEvent)
+                break;
+
 	    XESetWireToEvent (dpy, j, hooks->wire_to_event);
 	    XESetEventToWire (dpy, j, hooks->event_to_wire);
 	}
-- 
1.6.0.4



_______________________________________________
xorg mailing list
xorg@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/xorg

Reply via email to