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 | |
parent | c49ee670d39f11f5eea3bd621c7e918e41c20876 (diff) |
* Indent wrapped chat lines to avoid potential imitation exploits
Diffstat (limited to 'src')
-rw-r--r-- | src/cgame/cg_servercmds.c | 20 | ||||
-rw-r--r-- | src/client/cl_console.c | 2 | ||||
-rw-r--r-- | src/qcommon/common.c | 2 | ||||
-rw-r--r-- | src/qcommon/q_shared.c | 15 | ||||
-rw-r--r-- | src/qcommon/q_shared.h | 3 | ||||
-rw-r--r-- | src/ui/ui_shared.c | 70 |
6 files changed, 95 insertions, 17 deletions
diff --git a/src/cgame/cg_servercmds.c b/src/cgame/cg_servercmds.c index 260ea5d4..8026f196 100644 --- a/src/cgame/cg_servercmds.c +++ b/src/cgame/cg_servercmds.c @@ -984,30 +984,30 @@ static void CG_Say( int clientNum, saymode_t mode, const char *text ) if( cg_teamChatsOnly.integer ) ignore = "[skipnotify]"; - CG_Printf( "%s%s%s" S_COLOR_WHITE "%s " S_COLOR_GREEN "%s\n", - ignore, prefix, name, maybeColon, text ); + CG_Printf( "%s%s%s" S_COLOR_WHITE "%s %c" S_COLOR_GREEN "%s\n", + ignore, prefix, name, maybeColon, INDENT_MARKER, text ); break; case SAY_TEAM: - CG_Printf( "%s%s(%s" S_COLOR_WHITE ")%s%s " S_COLOR_CYAN "%s\n", - ignore, prefix, name, location, maybeColon, text ); + CG_Printf( "%s%s(%s" S_COLOR_WHITE ")%s%s %c" S_COLOR_CYAN "%s\n", + ignore, prefix, name, location, maybeColon, INDENT_MARKER, text ); break; case SAY_ADMINS: case SAY_ADMINS_PUBLIC: - CG_Printf( "%s%s%s%s" S_COLOR_WHITE "%s " S_COLOR_MAGENTA "%s\n", + CG_Printf( "%s%s%s%s" S_COLOR_WHITE "%s %c" S_COLOR_MAGENTA "%s\n", ignore, prefix, ( mode == SAY_ADMINS ) ? "[ADMIN]" : "[PLAYER]", - name, maybeColon, text ); + name, maybeColon, INDENT_MARKER, text ); break; case SAY_AREA: - CG_Printf( "%s%s<%s" S_COLOR_WHITE ">%s%s " S_COLOR_BLUE "%s\n", - ignore, prefix, name, location, maybeColon, text ); + CG_Printf( "%s%s<%s" S_COLOR_WHITE ">%s%s %c" S_COLOR_BLUE "%s\n", + ignore, prefix, name, location, maybeColon, INDENT_MARKER, text ); break; case SAY_PRIVMSG: case SAY_TPRIVMSG: color = ( mode == SAY_TPRIVMSG ) ? S_COLOR_CYAN : S_COLOR_GREEN; - CG_Printf( "%s%s[%s" S_COLOR_WHITE " -> %s" S_COLOR_WHITE "]%s %s%s\n", + CG_Printf( "%s%s[%s" S_COLOR_WHITE " -> %s" S_COLOR_WHITE "]%s %c%s%s\n", ignore, prefix, name, cgs.clientinfo[ cg.clientNum ].name, - maybeColon, color, text ); + maybeColon, INDENT_MARKER, color, text ); if( !ignore[0] ) CG_CenterPrint( va( "%sPrivate message from: " S_COLOR_WHITE "%s", color, name ), 200, GIANTCHAR_WIDTH * 4 ); diff --git a/src/client/cl_console.c b/src/client/cl_console.c index 939e003f..c2e59ea6 100644 --- a/src/client/cl_console.c +++ b/src/client/cl_console.c @@ -361,6 +361,8 @@ void CL_ConsolePrint( char *txt ) { switch (c) { + case INDENT_MARKER: + break; case '\n': Con_Linefeed (skipnotify); break; diff --git a/src/qcommon/common.c b/src/qcommon/common.c index d4593e08..ddd3c023 100644 --- a/src/qcommon/common.c +++ b/src/qcommon/common.c @@ -164,6 +164,8 @@ void QDECL Com_Printf( const char *fmt, ... ) { CL_ConsolePrint( msg ); #endif + Q_StripIndentMarker( msg ); + // echo to dedicated console and early console Sys_Print( msg ); diff --git a/src/qcommon/q_shared.c b/src/qcommon/q_shared.c index 6da13ad0..71da2734 100644 --- a/src/qcommon/q_shared.c +++ b/src/qcommon/q_shared.c @@ -935,6 +935,21 @@ int Q_CountChar(const char *string, char tocount) return count; } +void Q_StripIndentMarker(char *string) +{ + int i; + + for (i = 0; i < strlen(string); i++) { + if (string[i] == INDENT_MARKER) { + int j; + + for (j = i; j < strlen(string); j++) { + string[j] = string[j+1]; + } + } + } +} + void Q_ParseNewlines( char *dest, const char *src, int destsize ) { for( ; *src && destsize > 1; src++, destsize-- ) diff --git a/src/qcommon/q_shared.h b/src/qcommon/q_shared.h index 6eda5cd8..29cc4b9b 100644 --- a/src/qcommon/q_shared.h +++ b/src/qcommon/q_shared.h @@ -389,6 +389,9 @@ extern vec4_t colorDkGrey; #define S_COLOR_MAGENTA "^6" #define S_COLOR_WHITE "^7" +#define INDENT_MARKER '\v' +void Q_StripIndentMarker(char *string); + extern vec4_t g_color_table[8]; #define MAKERGB( v, r, g, b ) v[0]=r;v[1]=g;v[2]=b 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 ); |