[egl] shader: fix reliance on null terminated strings

Compiled in resources often will not contain a null terminator, as such
we must not use functions that rely on it. This implements a memsearch
function that performs like strstr on a buffer instead of a null
terminated string.
This commit is contained in:
Geoffrey McRae 2023-11-11 12:17:37 +11:00
parent 43f9a4c0e1
commit cce12508cc
3 changed files with 43 additions and 10 deletions

View File

@ -20,6 +20,7 @@
#include "shader.h" #include "shader.h"
#include "common/debug.h" #include "common/debug.h"
#include "common/stringutils.h"
#include "util.h" #include "util.h"
#include <stdlib.h> #include <stdlib.h>
@ -219,18 +220,22 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
if (useDMA) if (useDMA)
{ {
const char * search = "sampler2D"; const char search[] = "sampler2D";
const char * replace = "samplerExternalOES"; const char replace[] = "samplerExternalOES";
const char * src = fragment_code; const char * offset = NULL;
int instances = 0; int instances = 0;
while((src = strstr(src, search)))
while((offset = memsearch(
fragment_code, fragment_size,
search , sizeof(search)-1,
offset)))
{ {
++instances; ++instances;
src += strlen(search); offset += sizeof(search)-1;
} }
const int diff = (strlen(replace) - strlen(search)) * instances; const int diff = (sizeof(replace) - sizeof(search)) * instances;
const int newLen = fragment_size + diff; const int newLen = fragment_size + diff;
newCode = malloc(newLen + 1); newCode = malloc(newLen + 1);
if (!newCode) if (!newCode)
@ -239,7 +244,7 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
goto exit; goto exit;
} }
src = fragment_code; const char * src = fragment_code;
char * dst = newCode; char * dst = newCode;
for(int i = 0; i < instances; ++i) for(int i = 0; i < instances; ++i)
{ {
@ -248,10 +253,10 @@ bool egl_shaderCompile(EGL_Shader * this, const char * vertex_code,
memcpy(dst, src, offset); memcpy(dst, src, offset);
dst += offset; dst += offset;
src = pos + strlen(search); src = pos + sizeof(search)-1;
memcpy(dst, replace, strlen(replace)); memcpy(dst, replace, sizeof(replace)-1);
dst += strlen(replace); dst += sizeof(replace)-1;
} }
const int final = fragment_size - (src - fragment_code); const int final = fragment_size - (src - fragment_code);

View File

@ -37,4 +37,10 @@ bool str_containsValue(const char * list, char delimiter, const char * value);
// Local implementation of strdup // Local implementation of strdup
char * lg_strdup(const char *s); char * lg_strdup(const char *s);
// search a non null terminated buffer for a value
const char * memsearch(
const char * haystack, size_t haystackSize,
const char * needle , size_t needleSize ,
const char * offset);
#endif #endif

View File

@ -26,6 +26,7 @@
#include <errno.h> #include <errno.h>
#include "common/stringutils.h" #include "common/stringutils.h"
#include "common/debug.h"
int valloc_sprintf(char ** str, const char * format, va_list ap) int valloc_sprintf(char ** str, const char * format, va_list ap)
{ {
@ -110,3 +111,24 @@ char * lg_strdup(const char *s)
memcpy(out, s, len); memcpy(out, s, len);
return out; return out;
} }
const char * memsearch(
const char * haystack, size_t haystackSize,
const char * needle , size_t needleSize ,
const char * offset)
{
int i = 0;
if (offset)
{
DEBUG_ASSERT(offset >= haystack);
DEBUG_ASSERT(offset < haystack + haystackSize);
i = offset - haystack;
}
const int searchSize = haystackSize - needleSize + 1;
for(; i < searchSize; ++i)
if (memcmp(haystack + i, needle, needleSize) == 0)
return haystack + i;
return NULL;
}