[Mesa-dev] [PATCH] glx: Be more tolerant in glXImportContext (v2)

Adam Jackson ajax at redhat.com
Tue Sep 26 20:38:31 UTC 2017


Ugh the GLX code. __GLX_MAX_CONTEXT_PROPS is 3 because glxproto.h is
just a pile of ancient runes, so when the server begins sending more
than 3 context properties this code refuses to work _at all_.  Which is
all just silly. If _XReply succeeds, it will have buffered the whole
reply, we can just walk through each property one at a time.

v2: Now with no arbitrary limits. (Eric Anholt)

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 src/glx/glxcmds.c | 70 +++++++++++++++++++++++--------------------------------
 1 file changed, 29 insertions(+), 41 deletions(-)

diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c
index 29b94b8810..10c7c2c3eb 100644
--- a/src/glx/glxcmds.c
+++ b/src/glx/glxcmds.c
@@ -1403,15 +1403,9 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID)
    xGLXQueryContextReply reply;
    CARD8 opcode;
    struct glx_context *ctx;
-
-   /* This GLX implementation knows about 5 different properties, so
-    * allow the server to send us one of each.
-    */
-   int propList[5 * 2], *pProp, nPropListBytes;
-   int numProps;
-   int i, renderType;
-   XID share;
-   struct glx_config *mode;
+   int i, renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */
+   XID share = None;
+   struct glx_config *mode = NULL;
    uint32_t fbconfigID = 0;
    uint32_t visualID = 0;
    uint32_t screen = 0;
@@ -1469,42 +1463,36 @@ glXImportContextEXT(Display *dpy, GLXContextID contextID)
       req->context = contextID;
    }
 
-   _XReply(dpy, (xReply *) & reply, 0, False);
+   if (_XReply(dpy, (xReply *) & reply, 0, False) &&
+       reply.n < (INT32_MAX / 2)) {
 
-   if (reply.n <= __GLX_MAX_CONTEXT_PROPS)
-      nPropListBytes = reply.n * 2 * sizeof propList[0];
-   else
-      nPropListBytes = 0;
-   _XRead(dpy, (char *) propList, nPropListBytes);
+      for (i = 0; i < reply.n * 2; i++) {
+         int prop[2];
+
+         _XRead(dpy, (char *)prop, sizeof(prop));
+         switch (prop[0]) {
+         case GLX_SCREEN:
+            screen = prop[1];
+            got_screen = True;
+            break;
+         case GLX_SHARE_CONTEXT_EXT:
+            share = prop[1];
+            break;
+         case GLX_VISUAL_ID_EXT:
+            visualID = prop[1];
+            break;
+         case GLX_FBCONFIG_ID:
+            fbconfigID = prop[1];
+            break;
+         case GLX_RENDER_TYPE:
+            renderType = prop[1];
+            break;
+         }
+      }
+   }
    UnlockDisplay(dpy);
    SyncHandle();
 
-   numProps = nPropListBytes / (2 * sizeof(propList[0]));
-   share = None;
-   mode = NULL;
-   renderType = GLX_RGBA_TYPE; /* By default, assume RGBA context */
-   pProp = propList;
-
-   for (i = 0, pProp = propList; i < numProps; i++, pProp += 2)
-      switch (pProp[0]) {
-      case GLX_SCREEN:
-	 screen = pProp[1];
-	 got_screen = True;
-	 break;
-      case GLX_SHARE_CONTEXT_EXT:
-	 share = pProp[1];
-	 break;
-      case GLX_VISUAL_ID_EXT:
-	 visualID = pProp[1];
-	 break;
-      case GLX_FBCONFIG_ID:
-	 fbconfigID = pProp[1];
-	 break;
-      case GLX_RENDER_TYPE:
-	 renderType = pProp[1];
-	 break;
-      }
-
    if (!got_screen)
       return NULL;
 
-- 
2.14.1



More information about the mesa-dev mailing list