[client] egl: use new util_hasGLExt helper to check extensions

We previously used strstr, which can be prone to false positives when
the name of one extension is a substring of another extension.

This commit creates the helper function util_hasGLExt, which asserts
that the substring found in extension list is bounded by either spaces
or the beginning/end of the string.
This commit is contained in:
Quantum 2021-05-13 16:36:01 -04:00 committed by Geoffrey McRae
parent edbd6f6ade
commit f9a9953071
8 changed files with 47 additions and 7 deletions

View File

@ -35,6 +35,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "egl_dynprocs.h" #include "egl_dynprocs.h"
#include "common/types.h" #include "common/types.h"
#include "common/debug.h" #include "common/debug.h"
#include "util.h"
struct SDLDSState struct SDLDSState
{ {
@ -199,14 +200,14 @@ static EGLDisplay sdlGetEGLDisplay(void)
const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS); const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS);
if (strstr(early_exts, "EGL_KHR_platform_base") != NULL && if (util_hasGLExt(early_exts, "EGL_KHR_platform_base") &&
g_egl_dynProcs.eglGetPlatformDisplay) g_egl_dynProcs.eglGetPlatformDisplay)
{ {
DEBUG_INFO("Using eglGetPlatformDisplay"); DEBUG_INFO("Using eglGetPlatformDisplay");
return g_egl_dynProcs.eglGetPlatformDisplay(platform, native, NULL); return g_egl_dynProcs.eglGetPlatformDisplay(platform, native, NULL);
} }
if (strstr(early_exts, "EGL_EXT_platform_base") != NULL && if (util_hasGLExt(early_exts, "EGL_EXT_platform_base") &&
g_egl_dynProcs.eglGetPlatformDisplayEXT) g_egl_dynProcs.eglGetPlatformDisplayEXT)
{ {
DEBUG_INFO("Using eglGetPlatformDisplayEXT"); DEBUG_INFO("Using eglGetPlatformDisplayEXT");

View File

@ -28,6 +28,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "app.h" #include "app.h"
#include "common/debug.h" #include "common/debug.h"
#include "util.h"
#if defined(ENABLE_EGL) || defined(ENABLE_OPENGL) #if defined(ENABLE_EGL) || defined(ENABLE_OPENGL)
#include "egl_dynprocs.h" #include "egl_dynprocs.h"
@ -49,14 +50,14 @@ EGLDisplay waylandGetEGLDisplay(void)
const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS); const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS);
if (strstr(early_exts, "EGL_KHR_platform_wayland") != NULL && if (util_hasGLExt(early_exts, "EGL_KHR_platform_wayland") &&
g_egl_dynProcs.eglGetPlatformDisplay) g_egl_dynProcs.eglGetPlatformDisplay)
{ {
DEBUG_INFO("Using eglGetPlatformDisplay"); DEBUG_INFO("Using eglGetPlatformDisplay");
return g_egl_dynProcs.eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, native, NULL); return g_egl_dynProcs.eglGetPlatformDisplay(EGL_PLATFORM_WAYLAND_KHR, native, NULL);
} }
if (strstr(early_exts, "EGL_EXT_platform_wayland") != NULL && if (util_hasGLExt(early_exts, "EGL_EXT_platform_wayland") &&
g_egl_dynProcs.eglGetPlatformDisplayEXT) g_egl_dynProcs.eglGetPlatformDisplayEXT)
{ {
DEBUG_INFO("Using eglGetPlatformDisplayEXT"); DEBUG_INFO("Using eglGetPlatformDisplayEXT");

View File

@ -42,6 +42,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "app.h" #include "app.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/time.h" #include "common/time.h"
#include "util.h"
#define _NET_WM_STATE_REMOVE 0 #define _NET_WM_STATE_REMOVE 0
#define _NET_WM_STATE_ADD 1 #define _NET_WM_STATE_ADD 1
@ -901,14 +902,14 @@ static EGLDisplay x11GetEGLDisplay(void)
EGLDisplay ret; EGLDisplay ret;
const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS); const char *early_exts = eglQueryString(NULL, EGL_EXTENSIONS);
if (strstr(early_exts, "EGL_KHR_platform_base") != NULL && if (util_hasGLExt(early_exts, "EGL_KHR_platform_base") &&
g_egl_dynProcs.eglGetPlatformDisplay) g_egl_dynProcs.eglGetPlatformDisplay)
{ {
DEBUG_INFO("Using eglGetPlatformDisplay"); DEBUG_INFO("Using eglGetPlatformDisplay");
ret = g_egl_dynProcs.eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR, ret = g_egl_dynProcs.eglGetPlatformDisplay(EGL_PLATFORM_X11_KHR,
x11.display, NULL); x11.display, NULL);
} }
else if (strstr(early_exts, "EGL_EXT_platform_base") != NULL && else if (util_hasGLExt(early_exts, "EGL_EXT_platform_base") &&
g_egl_dynProcs.eglGetPlatformDisplayEXT) g_egl_dynProcs.eglGetPlatformDisplayEXT)
{ {
DEBUG_INFO("Using eglGetPlatformDisplayEXT"); DEBUG_INFO("Using eglGetPlatformDisplayEXT");

View File

@ -32,6 +32,7 @@ void util_cursorToInt(double ex, double ey, int *x, int *y);
bool util_guestCurToLocal(struct DoublePoint *local); bool util_guestCurToLocal(struct DoublePoint *local);
void util_localCurToGuest(struct DoublePoint *guest); void util_localCurToGuest(struct DoublePoint *guest);
void util_rotatePoint(struct DoublePoint *point); void util_rotatePoint(struct DoublePoint *point);
bool util_hasGLExt(const char * exts, const char * ext);
static inline double util_clamp(double x, double min, double max) static inline double util_clamp(double x, double min, double max)
{ {

View File

@ -698,7 +698,7 @@ bool egl_render_startup(void * opaque)
if (g_egl_dynProcs.glEGLImageTargetTexture2DOES) if (g_egl_dynProcs.glEGLImageTargetTexture2DOES)
{ {
if (strstr(client_exts, "EGL_EXT_image_dma_buf_import") != NULL) if (util_hasGLExt(client_exts, "EGL_EXT_image_dma_buf_import"))
{ {
/* /*
* As of version 455.45.01 NVidia started advertising support for this * As of version 455.45.01 NVidia started advertising support for this

View File

@ -21,9 +21,11 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include "main.h" #include "main.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/stringutils.h"
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <assert.h> #include <assert.h>
#include <math.h> #include <math.h>
@ -207,3 +209,8 @@ void util_rotatePoint(struct DoublePoint *point)
break; break;
} }
} }
bool util_hasGLExt(const char * exts, const char * ext)
{
return str_containsValue(exts, ' ', ext);
}

View File

@ -20,6 +20,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#ifndef _H_LG_COMMON_STRINGUTILS #ifndef _H_LG_COMMON_STRINGUTILS
#define _H_LG_COMMON_STRINGUTILS #define _H_LG_COMMON_STRINGUTILS
#include <stdbool.h>
// vsprintf but with buffer allocation // vsprintf but with buffer allocation
int valloc_sprintf(char ** str, const char * format, va_list ap) int valloc_sprintf(char ** str, const char * format, va_list ap)
__attribute__ ((format (printf, 2, 0))); __attribute__ ((format (printf, 2, 0)));
@ -28,4 +30,7 @@ int valloc_sprintf(char ** str, const char * format, va_list ap)
int alloc_sprintf(char ** str, const char * format, ...) int alloc_sprintf(char ** str, const char * format, ...)
__attribute__ ((format (printf, 2, 3))); __attribute__ ((format (printf, 2, 3)));
// Find value in a list separated by delimiter.
bool str_containsValue(const char * list, char delimiter, const char * value);
#endif #endif

View File

@ -17,9 +17,13 @@ this program; if not, write to the Free Software Foundation, Inc., 59 Temple
Place, Suite 330, Boston, MA 02111-1307 USA Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#include <stdbool.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
#include <string.h>
#include "common/stringutils.h"
int valloc_sprintf(char ** str, const char * format, va_list ap) int valloc_sprintf(char ** str, const char * format, va_list ap)
{ {
@ -64,3 +68,23 @@ int alloc_sprintf(char ** str, const char * format, ...)
va_end(ap); va_end(ap);
return ret; return ret;
} }
bool str_containsValue(const char * list, char delimiter, const char * value)
{
size_t len = strlen(value);
const char span[] = {delimiter, '\0'};
while (*list)
{
if (*list == delimiter)
{
++list;
continue;
}
size_t n = strcspn(list, span);
if (n == len && strncmp(value, list, n) == 0)
return true;
list += n;
}
return false;
}