glx: Be more tolerant in glXImportContext (v2)

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@redhat.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Adam Jackson
2017-09-26 16:38:31 -04:00
parent 23a09b4f67
commit 0852162950

View File

@@ -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;