From 3ec2b02dce9496e06f2b4dcda8840fd216114711 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 2 Jun 2013 21:55:19 -0500 Subject: [PATCH] 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. --- code/qcommon/q_shared.c | 8 ++++---- code/qcommon/q_shared.h | 2 +- code/renderergl1/tr_shader.c | 26 ++++++++++++++++++-------- code/renderergl2/tr_shader.c | 26 ++++++++++++++++++-------- 4 files changed, 41 insertions(+), 21 deletions(-) diff --git a/code/qcommon/q_shared.c b/code/qcommon/q_shared.c index af80df8f..0d1e5eb4 100644 --- a/code/qcommon/q_shared.c +++ b/code/qcommon/q_shared.c @@ -552,16 +552,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 ) { @@ -573,6 +571,8 @@ void SkipBracedSection (char **program) { } } } while( depth && *program ); + + return ( depth == 0 ); } /* diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h index 786fca25..b7f03fda 100644 --- a/code/qcommon/q_shared.h +++ b/code/qcommon/q_shared.h @@ -752,7 +752,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/code/renderergl1/tr_shader.c b/code/renderergl1/tr_shader.c index 611bebb0..2d30f603 100644 --- a/code/renderergl1/tr_shader.c +++ b/code/renderergl1/tr_shader.c @@ -2382,7 +2382,7 @@ static char *FindShaderInShaderText( const char *shadername ) { } else { // skip the definition - SkipBracedSection( &p ); + SkipBracedSection( &p, 0 ); } } @@ -2916,6 +2916,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 @@ -2945,15 +2947,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') { @@ -2963,8 +2967,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; + } } @@ -3008,7 +3018,7 @@ static void ScanAndLoadShaderFiles( void ) hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTableSizes[hash]++; size++; - SkipBracedSection(&p); + SkipBracedSection(&p, 0); } size += MAX_SHADERTEXT_HASH; @@ -3034,7 +3044,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/code/renderergl2/tr_shader.c b/code/renderergl2/tr_shader.c index 416b7f17..6dbe089a 100644 --- a/code/renderergl2/tr_shader.c +++ b/code/renderergl2/tr_shader.c @@ -3018,7 +3018,7 @@ static char *FindShaderInShaderText( const char *shadername ) { } else { // skip the definition - SkipBracedSection( &p ); + SkipBracedSection( &p, 0 ); } } @@ -3542,6 +3542,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 @@ -3585,15 +3587,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') { @@ -3603,8 +3607,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; + } } @@ -3648,7 +3658,7 @@ static void ScanAndLoadShaderFiles( void ) hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTableSizes[hash]++; size++; - SkipBracedSection(&p); + SkipBracedSection(&p, 0); } size += MAX_SHADERTEXT_HASH; @@ -3674,7 +3684,7 @@ static void ScanAndLoadShaderFiles( void ) hash = generateHashValue(token, MAX_SHADERTEXT_HASH); shaderTextHashTable[hash][shaderTextHashTableSizes[hash]++] = oldp; - SkipBracedSection(&p); + SkipBracedSection(&p, 0); } return;