summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author/dev/humancontroller <devhc@example.com>2014-07-13 18:56:40 +0200
committer/dev/humancontroller <devhc@example.com>2017-03-09 13:51:11 +0100
commit00a26aa43455d82cbdda151ea90971c1f60df4fe (patch)
tree26f0245355e21d8b95b6f134abc921a83d935b2f
parent10121326fbf07b701038893ecdb19f672c29c11e (diff)
make wrap caching a bit more secure
-rw-r--r--src/ui/ui_shared.c61
1 files changed, 34 insertions, 27 deletions
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c
index fdee188a..aadad31e 100644
--- a/src/ui/ui_shared.c
+++ b/src/ui/ui_shared.c
@@ -4415,57 +4415,69 @@ const char *Item_Text_Wrap( const char *text, float scale, float width )
typedef struct
{
- char text[ MAX_WRAP_TEXT * MAX_WRAP_LINES ]; //FIXME: augment with hash?
+ char text[ MAX_WRAP_TEXT * MAX_WRAP_LINES ];
rectDef_t rect;
float scale;
char lines[ MAX_WRAP_LINES ][ MAX_WRAP_TEXT ];
float lineCoords[ MAX_WRAP_LINES ][ 2 ];
int numLines;
-}
-
-wrapCache_t;
+} wrapCache_t;
static wrapCache_t wrapCache[ MAX_WRAP_CACHE ];
+static qboolean cacheCreationFailed = qfalse;
static int cacheWriteIndex = 0;
static int cacheReadIndex = 0;
static int cacheReadLineNum = 0;
-static void UI_CreateCacheEntry( const char *text, rectDef_t *rect, float scale )
+static void UI_CreateCacheEntry( const char *text, const rectDef_t *rect, float scale )
{
wrapCache_t *cacheEntry = &wrapCache[ cacheWriteIndex ];
- Q_strncpyz( cacheEntry->text, text, sizeof( cacheEntry->text ) );
- cacheEntry->rect.x = rect->x;
- cacheEntry->rect.y = rect->y;
- cacheEntry->rect.w = rect->w;
- cacheEntry->rect.h = rect->h;
- cacheEntry->scale = scale;
- cacheEntry->numLines = 0;
+ if( strlen( text ) >= sizeof( cacheEntry->text ) )
+ {
+ cacheCreationFailed = qtrue;
+ return;
+ }
+
+ strcpy( cacheEntry->text, text );
+ cacheEntry->rect = *rect;
+ cacheEntry->scale = scale;
+ cacheEntry->numLines = 0;
}
static void UI_AddCacheEntryLine( const char *text, float x, float y )
{
wrapCache_t *cacheEntry = &wrapCache[ cacheWriteIndex ];
- if( cacheEntry->numLines >= MAX_WRAP_LINES )
+ if( cacheCreationFailed )
return;
- Q_strncpyz( cacheEntry->lines[ cacheEntry->numLines ], text,
- sizeof( cacheEntry->lines[ 0 ] ) );
+ if( cacheEntry->numLines >= MAX_WRAP_LINES ||
+ strlen( text ) >= sizeof( cacheEntry->lines[ 0 ] ) )
+ {
+ cacheCreationFailed = qtrue;
+ return;
+ }
+ strcpy( cacheEntry->lines[ cacheEntry->numLines ], text );
cacheEntry->lineCoords[ cacheEntry->numLines ][ 0 ] = x;
-
cacheEntry->lineCoords[ cacheEntry->numLines ][ 1 ] = y;
-
cacheEntry->numLines++;
}
static void UI_FinishCacheEntry( void )
{
- cacheWriteIndex = ( cacheWriteIndex + 1 ) % MAX_WRAP_CACHE;
+ if( cacheCreationFailed )
+ {
+ wrapCache[ cacheWriteIndex ].text[ 0 ] = '\0';
+ wrapCache[ cacheWriteIndex ].numLines = 0;
+ cacheCreationFailed = qfalse;
+ }
+ else
+ cacheWriteIndex = ( cacheWriteIndex + 1 ) % MAX_WRAP_CACHE;
}
-static qboolean UI_CheckWrapCache( const char *text, rectDef_t *rect, float scale )
+static qboolean UI_CheckWrapCache( const char *text, const rectDef_t *rect, float scale )
{
int i;
@@ -4473,27 +4485,24 @@ static qboolean UI_CheckWrapCache( const char *text, rectDef_t *rect, float scal
{
wrapCache_t *cacheEntry = &wrapCache[ i ];
- if( strcmp( text, cacheEntry->text ) )
- continue;
-
if( rect->x != cacheEntry->rect.x ||
rect->y != cacheEntry->rect.y ||
rect->w != cacheEntry->rect.w ||
rect->h != cacheEntry->rect.h )
continue;
+ if( strcmp( text, cacheEntry->text ) )
+ continue;
+
if( cacheEntry->scale != scale )
continue;
- // This is a match
cacheReadIndex = i;
-
cacheReadLineNum = 0;
return qtrue;
}
- // No match - wrap isn't cached
return qfalse;
}
@@ -4505,9 +4514,7 @@ static qboolean UI_NextWrapLine( const char **text, float *x, float *y )
return qfalse;
*text = cacheEntry->lines[ cacheReadLineNum ];
-
*x = cacheEntry->lineCoords[ cacheReadLineNum ][ 0 ];
-
*y = cacheEntry->lineCoords[ cacheReadLineNum ][ 1 ];
cacheReadLineNum++;