glx: createcontext: silence analyzer warning and make code easier to understand

This warning is probably a false alarm, but it's trivial to fix.

| ../glx/createcontext.c: In function ‘__glXDisp_CreateContextAttribsARB’:
| ../glx/createcontext.c:172:24: warning: dereference of NULL ‘0’ [CWE-476] [-Wanalyzer-null-dereference]
|   172 |         switch (attribs[i * 2]) {
|       |                 ~~~~~~~^~~~~~~

The situation is too complex for the analyzer to handle:
(but also not immediately clear for the human reader)

* `attribs` is only NULL when req->numAttribs is 0
* in that case, the for loop is no-op, so `attribs` won't ever be deref'ed.

We can make it easier for both analyzer as well as human reader by just putting
the whole loop into an `if (req->numAttribs)` and assigning it inside there.
There shouldn't be any (practically measurable) extra cost.

Signed-off-by: Enrico Weigelt, metux IT consult <info@metux.net>
This commit is contained in:
Enrico Weigelt, metux IT consult 2025-05-06 14:31:42 +02:00
parent 2b3bbce30b
commit 9ee96639d7

View File

@ -80,8 +80,6 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
{ {
ClientPtr client = cl->client; ClientPtr client = cl->client;
xGLXCreateContextAttribsARBReq *req = (xGLXCreateContextAttribsARBReq *) pc; xGLXCreateContextAttribsARBReq *req = (xGLXCreateContextAttribsARBReq *) pc;
int32_t *attribs = (req->numAttribs != 0) ? (int32_t *) (req + 1) : NULL;
unsigned i;
int major_version = 1; int major_version = 1;
int minor_version = 0; int minor_version = 0;
uint32_t flags = 0; uint32_t flags = 0;
@ -168,63 +166,67 @@ __glXDisp_CreateContextAttribsARB(__GLXclientState * cl, GLbyte * pc)
} }
} }
for (i = 0; i < req->numAttribs; i++) { int32_t *attribs = NULL;
switch (attribs[i * 2]) {
case GLX_CONTEXT_MAJOR_VERSION_ARB:
major_version = attribs[2 * i + 1];
break;
case GLX_CONTEXT_MINOR_VERSION_ARB: if (req->numAttribs) {
minor_version = attribs[2 * i + 1]; attribs = (int32_t *) (req + 1);
break; for (int i = 0; i < req->numAttribs; i++) {
switch (attribs[i * 2]) {
case GLX_CONTEXT_MAJOR_VERSION_ARB:
major_version = attribs[2 * i + 1];
break;
case GLX_CONTEXT_FLAGS_ARB: case GLX_CONTEXT_MINOR_VERSION_ARB:
flags = attribs[2 * i + 1]; minor_version = attribs[2 * i + 1];
break; break;
case GLX_RENDER_TYPE: case GLX_CONTEXT_FLAGS_ARB:
/* Not valid for GLX_EXT_no_config_context */ flags = attribs[2 * i + 1];
if (!req->fbconfig) break;
return BadValue;
render_type = attribs[2 * i + 1];
break;
case GLX_CONTEXT_PROFILE_MASK_ARB: case GLX_RENDER_TYPE:
profile = attribs[2 * i + 1]; /* Not valid for GLX_EXT_no_config_context */
break; if (!req->fbconfig)
return BadValue;
render_type = attribs[2 * i + 1];
break;
case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB: case GLX_CONTEXT_PROFILE_MASK_ARB:
reset = attribs[2 * i + 1]; profile = attribs[2 * i + 1];
if (reset != GLX_NO_RESET_NOTIFICATION_ARB break;
&& reset != GLX_LOSE_CONTEXT_ON_RESET_ARB)
return BadValue;
break; case GLX_CONTEXT_RESET_NOTIFICATION_STRATEGY_ARB:
reset = attribs[2 * i + 1];
if (reset != GLX_NO_RESET_NOTIFICATION_ARB
&& reset != GLX_LOSE_CONTEXT_ON_RESET_ARB)
return BadValue;
break;
case GLX_CONTEXT_RELEASE_BEHAVIOR_ARB: case GLX_CONTEXT_RELEASE_BEHAVIOR_ARB:
flush = attribs[2 * i + 1]; flush = attribs[2 * i + 1];
if (flush != GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB if (flush != GLX_CONTEXT_RELEASE_BEHAVIOR_NONE_ARB
&& flush != GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB) && flush != GLX_CONTEXT_RELEASE_BEHAVIOR_FLUSH_ARB)
return BadValue; return BadValue;
break; break;
case GLX_SCREEN: case GLX_SCREEN:
/* Only valid for GLX_EXT_no_config_context */ /* Only valid for GLX_EXT_no_config_context */
if (req->fbconfig) if (req->fbconfig)
return BadValue; return BadValue;
/* Must match the value in the request header */ /* Must match the value in the request header */
if (attribs[2 * i + 1] != req->screen) if (attribs[2 * i + 1] != req->screen)
return BadValue; return BadValue;
break; break;
case GLX_CONTEXT_OPENGL_NO_ERROR_ARB: case GLX_CONTEXT_OPENGL_NO_ERROR_ARB:
/* ignore */ /* ignore */
break; break;
default: default:
if (!req->isDirect) if (!req->isDirect)
return BadValue; return BadValue;
break; break;
}
} }
} }