diff options
author | Tim Angus <tim@ngus.net> | 2009-11-03 23:38:49 +0000 |
---|---|---|
committer | Tim Angus <tim@ngus.net> | 2013-01-03 00:17:17 +0000 |
commit | e9551ec91ffc7fb144eac71c5b65501c2c40f39d (patch) | |
tree | 0a975d9804f5f7a0940b6740061c1a098cb6c39a /src/ui | |
parent | c49ee670d39f11f5eea3bd621c7e918e41c20876 (diff) |
* Indent wrapped chat lines to avoid potential imitation exploits
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/ui_shared.c | 70 |
1 files changed, 63 insertions, 7 deletions
diff --git a/src/ui/ui_shared.c b/src/ui/ui_shared.c index fcf359f1..2e54df2b 100644 --- a/src/ui/ui_shared.c +++ b/src/ui/ui_shared.c @@ -1905,6 +1905,32 @@ qboolean UI_Text_IsEmoticon( const char *s, qboolean *escaped, return qfalse; } +static float UI_Parse_Indent( const char **text ) +{ + char indentWidth[ MAX_STRING_CHARS ]; + char *p = indentWidth; + int numChars; + float pixels; + + Q_strncpyz( indentWidth, *text, MAX_STRING_CHARS ); + + while( isdigit( *p ) || *p == '.' ) + p++; + + if( *p != INDENT_MARKER ) + return 0.0f; + + *p++ = '\0'; + numChars = ( p - indentWidth ); + p = indentWidth; + + if( !Float_Parse( &p, &pixels ) ) + return 0.0f; + + (*text) += numChars; + + return pixels; +} float UI_Text_Width( const char *text, float scale, int limit ) { @@ -1919,6 +1945,7 @@ float UI_Text_Width( const char *text, float scale, int limit ) float emoticonW; int emoticonWidth; int emoticons = 0; + float indentWidth = 0.0f; if( scale <= DC->getCVarValue( "ui_smallFont" ) ) font = &DC->Assets.smallFont; @@ -1937,6 +1964,7 @@ float UI_Text_Width( const char *text, float scale, int limit ) len = limit; count = 0; + indentWidth = UI_Parse_Indent( &s ); while( s && *s && count < len ) { @@ -1948,6 +1976,12 @@ float UI_Text_Width( const char *text, float scale, int limit ) continue; } + if( *s == INDENT_MARKER ) + { + s++; + continue; + } + if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen, NULL, &emoticonWidth ) ) { @@ -1967,7 +2001,7 @@ float UI_Text_Width( const char *text, float scale, int limit ) } } - return ( out * useScale ) + ( emoticons * emoticonW ); + return ( out * useScale ) + ( emoticons * emoticonW ) + indentWidth; } float UI_Text_Height( const char *text, float scale, int limit ) @@ -2114,6 +2148,8 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus DC->setColor( color ); memcpy( &newColor[0], &color[0], sizeof( vec4_t ) ); + x += UI_Parse_Indent( &s ); + while( s && *s && count < len ) { glyph = &font->glyphs[ (int)*s ]; @@ -2136,6 +2172,12 @@ static void UI_Text_Paint_Generic( float x, float y, float scale, float gapAdjus continue; } + if( *s == INDENT_MARKER ) + { + s++; + continue; + } + if( UI_Text_IsEmoticon( s, &emoticonEscaped, &emoticonLen, &emoticonHandle, &emoticonWidth ) ) { @@ -4383,9 +4425,11 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) char c[ 3 ] = ""; const char *p = text; const char *eol; - const char *q = NULL, *qMinus1 = NULL; + const char *q = NULL; unsigned int testLength; unsigned int i; + float indentWidth = 0.0f; + float testWidth; if( strlen( text ) >= sizeof( out ) ) return NULL; @@ -4394,14 +4438,17 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) while( *p ) { - testLength = 1; eol = p; q = p + 1; + testLength = 0; + testWidth = width - indentWidth; SkipColorCodes( &q, c ); - while( UI_Text_Width( p, scale, testLength ) < width ) + while( testLength == 0 || UI_Text_Width( p, scale, testLength ) < testWidth ) { + qboolean previousCharIsSpace = qfalse; + // Remaining string is too short to wrap if( testLength >= strlen( p ) ) { @@ -4415,10 +4462,13 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) SkipColorCodes( &q, c ); SkipEmoticons( &q ); - qMinus1 = q; + previousCharIsSpace = isspace( *q ); q++; } + if( testLength > 0 && *q == INDENT_MARKER ) + indentWidth = UI_Text_Width( p, scale, testLength ); + // Some color escapes might still be present SkipColorCodes( &q, c ); SkipEmoticons( &q ); @@ -4430,7 +4480,7 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) break; } - if( !isspace( *qMinus1 ) && isspace( *q ) ) + if( !previousCharIsSpace && isspace( *q ) ) eol = q; testLength++; @@ -4450,14 +4500,20 @@ const char *Item_Text_Wrap( const char *text, float scale, float width ) if( out[ strlen( out ) - 1 ] == '\n' ) { - // The line is deliberately broken, clear the color + // The line is deliberately broken, clear the color and + // any current indent c[ 0 ] = '\0'; + indentWidth = 0.0f; } else { // Add a \n if it's not there already Q_strcat( out, sizeof( out ), "\n" ); + // Insert a pixel indent on the next line + if( indentWidth > 0.0f ) + Q_strcat( out, sizeof( out ), va( "%f%c", indentWidth, INDENT_MARKER ) ); + // Skip leading whitespace on next line and save the // last color code SkipWhiteSpace( &p, c ); |