summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZack Middleton <zturtleman@gmail.com>2013-06-02 21:55:19 -0500
committerTim Angus <tim@ngus.net>2014-06-17 17:43:32 +0100
commit9d80a63e44f513ec984375af62969a738a6bbee3 (patch)
tree417c1cfcd1b31256e7c4018918a0f8fb8f1a879c
parentf454aeaa8376d36e373eab69b877b67e8f9a661d (diff)
Check for shaders without closing brace
Shaders without closing brace can eat shaders in other files. Pass depth to SkipBracedSection instead of reparsing text as it messed up parse line numbers.
-rw-r--r--src/qcommon/q_shared.c8
-rw-r--r--src/qcommon/q_shared.h2
-rw-r--r--src/renderergl1/tr_shader.c26
-rw-r--r--src/renderergl2/tr_shader.c26
4 files changed, 41 insertions, 21 deletions
diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c
index 9cea9bda..ea365b55 100644
--- a/src/qcommon/q_shared.c
+++ b/src/qcommon/q_shared.c
@@ -553,16 +553,14 @@ void COM_MatchToken( char **buf_p, char *match ) {
=================
SkipBracedSection
-The next token should be an open brace.
+The next token should be an open brace or set depth to 1 if already parsed it.
Skips until a matching close brace is found.
Internal brace depths are properly skipped.
=================
*/
-void SkipBracedSection (char **program) {
+qboolean SkipBracedSection (char **program, int depth) {
char *token;
- int depth;
- depth = 0;
do {
token = COM_ParseExt( program, qtrue );
if( token[1] == 0 ) {
@@ -574,6 +572,8 @@ void SkipBracedSection (char **program) {
}
}
} while( depth && *program );
+
+ return ( depth == 0 );
}
/*
diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h
index a85e3473..88322482 100644
--- a/src/qcommon/q_shared.h
+++ b/src/qcommon/q_shared.h
@@ -801,7 +801,7 @@ typedef struct pc_token_s
void COM_MatchToken( char**buf_p, char *match );
-void SkipBracedSection (char **program);
+qboolean SkipBracedSection (char **program, int depth);
void SkipRestOfLine ( char **data );
void Parse1DMatrix (char **buf_p, int x, float *m);
diff --git a/src/renderergl1/tr_shader.c b/src/renderergl1/tr_shader.c
index 1d7aeee3..76ac27ca 100644
--- a/src/renderergl1/tr_shader.c
+++ b/src/renderergl1/tr_shader.c
@@ -2383,7 +2383,7 @@ static char *FindShaderInShaderText( const char *shadername ) {
}
else {
// skip the definition
- SkipBracedSection( &p );
+ SkipBracedSection( &p, 0 );
}
}
@@ -2917,6 +2917,8 @@ static void ScanAndLoadShaderFiles( void )
int i;
char *oldp, *token, *hashMem, *textEnd;
int shaderTextHashTableSizes[MAX_SHADERTEXT_HASH], hash, size;
+ char shaderName[MAX_QPATH];
+ int shaderLine;
long sum = 0, summand;
// scan for shader files
@@ -2946,15 +2948,17 @@ static void ScanAndLoadShaderFiles( void )
// Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
p = buffers[i];
+ COM_BeginParseSession(filename);
while(1)
{
token = COM_ParseExt(&p, qtrue);
if(!*token)
break;
-
- oldp = p;
-
+
+ Q_strncpyz(shaderName, token, sizeof(shaderName));
+ shaderLine = COM_GetCurrentParseLine();
+
token = COM_ParseExt(&p, qtrue);
if(token[0] != '{' || token[1] != '\0')
{
@@ -2964,8 +2968,14 @@ static void ScanAndLoadShaderFiles( void )
break;
}
- SkipBracedSection(&oldp);
- p = oldp;
+ if(!SkipBracedSection(&p, 1))
+ {
+ ri.Printf(PRINT_WARNING, "WARNING: Ignoring shader file %s. Shader \"%s\" on line %d missing closing brace.\n",
+ filename, shaderName, shaderLine);
+ ri.FS_FreeFile(buffers[i]);
+ buffers[i] = NULL;
+ break;
+ }
}
@@ -3009,7 +3019,7 @@ static void ScanAndLoadShaderFiles( void )
hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
shaderTextHashTableSizes[hash]++;
size++;
- SkipBracedSection(&p);
+ SkipBracedSection(&p, 0);
}
size += MAX_SHADERTEXT_HASH;
@@ -3035,7 +3045,7 @@ static void ScanAndLoadShaderFiles( void )
hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
shaderTextHashTable[hash][shaderTextHashTableSizes[hash]++] = oldp;
- SkipBracedSection(&p);
+ SkipBracedSection(&p, 0);
}
return;
diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c
index 5aaccb3c..63d89025 100644
--- a/src/renderergl2/tr_shader.c
+++ b/src/renderergl2/tr_shader.c
@@ -3019,7 +3019,7 @@ static char *FindShaderInShaderText( const char *shadername ) {
}
else {
// skip the definition
- SkipBracedSection( &p );
+ SkipBracedSection( &p, 0 );
}
}
@@ -3543,6 +3543,8 @@ static void ScanAndLoadShaderFiles( void )
int i;
char *oldp, *token, *hashMem, *textEnd;
int shaderTextHashTableSizes[MAX_SHADERTEXT_HASH], hash, size;
+ char shaderName[MAX_QPATH];
+ int shaderLine;
long sum = 0, summand;
// scan for shader files
@@ -3586,15 +3588,17 @@ static void ScanAndLoadShaderFiles( void )
// Do a simple check on the shader structure in that file to make sure one bad shader file cannot fuck up all other shaders.
p = buffers[i];
+ COM_BeginParseSession(filename);
while(1)
{
token = COM_ParseExt(&p, qtrue);
if(!*token)
break;
-
- oldp = p;
-
+
+ Q_strncpyz(shaderName, token, sizeof(shaderName));
+ shaderLine = COM_GetCurrentParseLine();
+
token = COM_ParseExt(&p, qtrue);
if(token[0] != '{' || token[1] != '\0')
{
@@ -3604,8 +3608,14 @@ static void ScanAndLoadShaderFiles( void )
break;
}
- SkipBracedSection(&oldp);
- p = oldp;
+ if(!SkipBracedSection(&p, 1))
+ {
+ ri.Printf(PRINT_WARNING, "WARNING: Ignoring shader file %s. Shader \"%s\" on line %d missing closing brace.\n",
+ filename, shaderName, shaderLine);
+ ri.FS_FreeFile(buffers[i]);
+ buffers[i] = NULL;
+ break;
+ }
}
@@ -3649,7 +3659,7 @@ static void ScanAndLoadShaderFiles( void )
hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
shaderTextHashTableSizes[hash]++;
size++;
- SkipBracedSection(&p);
+ SkipBracedSection(&p, 0);
}
size += MAX_SHADERTEXT_HASH;
@@ -3675,7 +3685,7 @@ static void ScanAndLoadShaderFiles( void )
hash = generateHashValue(token, MAX_SHADERTEXT_HASH);
shaderTextHashTable[hash][shaderTextHashTableSizes[hash]++] = oldp;
- SkipBracedSection(&p);
+ SkipBracedSection(&p, 0);
}
return;