Skip to content

Commit

Permalink
Fixed another buffer overflow in what was WI_DrawParamText... This fu…
Browse files Browse the repository at this point in the history
…nction needs a complete rewrite.

Added a default leading argument to GL_DrawText and fixed leading calculation to use the actual height of the last drawn line rather than a predetermined height.
Removed character filtering in InFine - this is handled automatically elsewhere.
  • Loading branch information
danij-deng committed May 31, 2010
1 parent be3b366 commit aa73a58
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 56 deletions.
2 changes: 1 addition & 1 deletion doomsday/engine/api/dd_compositefont.h
Expand Up @@ -62,7 +62,7 @@ void R_ResetTextTypeInTimer(void);
/**
* Text strings: A block of possibly formatted and/or multi-line text.
*/
void GL_DrawText(const char* string, int x, int y, compositefontid_t font, short flags, int defTracking, float defRed, float defGreen, float defBlue, float defAlpha, float defGlitter, float defShadow, boolean defCase);
void GL_DrawText(const char* string, int x, int y, compositefontid_t font, short flags, float defLeading, int defTracking, float defRed, float defGreen, float defBlue, float defAlpha, float defGlitter, float defShadow, boolean defCase);

// Utility routines:
void GL_TextDimensions(int* width, int* height, const char* string, compositefontid_t font);
Expand Down
26 changes: 17 additions & 9 deletions doomsday/engine/portable/src/gl_drawcompositefont.c
Expand Up @@ -38,7 +38,7 @@
#define DEFAULT_FONTID (0)
#define DEFAULT_GLITTER (0)
#define DEFAULT_SHADOW (0)
#define DEFAULT_LEADING (.25)
#define DEFAULT_LEADING (.5)
#define DEFAULT_TRACKING (0)
#define DEFAULT_DRAWFLAGS (DTF_ALIGN_TOPLEFT|DTF_NO_EFFECTS)
#define DEFAULT_INITIALCOUNT (0)
Expand Down Expand Up @@ -567,17 +567,18 @@ static void initDrawTextState(drawtextstate_t* state)
* Draw a string of text controlled by parameter blocks.
*/
void GL_DrawText(const char* inString, int x, int y, compositefontid_t defFont,
short flags, int defTracking, float defRed, float defGreen, float defBlue, float defAlpha,
short flags, float defLeading, int defTracking, float defRed, float defGreen, float defBlue, float defAlpha,
float defGlitter, float defShadow, boolean defCase)
{
#define SMALLBUFF_SIZE 80
#define SMALLBUFF_SIZE (80)
#define MAX_FRAGMENTLENGTH (256)

float cx = (float) x, cy = (float) y, width = 0, extraScale;
char smallBuff[SMALLBUFF_SIZE+1], *bigBuff = NULL;
char temp[256], *str, *string, *end;
char temp[MAX_FRAGMENTLENGTH+1], *str, *string, *end;
drawtextstate_t state;
size_t charCount = 0;
int curCase = -1;
int curCase = -1, lastLineHeight;
size_t len;

if(!inited)
Expand Down Expand Up @@ -614,8 +615,11 @@ void GL_DrawText(const char* inString, int x, int y, compositefontid_t defFont,
state.glitter = defGlitter;
state.shadow = defShadow;
state.tracking = defTracking;
state.leading = defLeading;
state.caseScale = defCase;

lastLineHeight = GL_CharHeight('A', state.font) * state.scaleY;

string = str;
while(*string)
{
Expand All @@ -633,7 +637,7 @@ void GL_DrawText(const char* inString, int x, int y, compositefontid_t defFont,
do
{
cx = (float) x;
cy += GL_CharHeight(0, oldFont) * (1+oldLeading) * oldScaleY;
cy += lastLineHeight * (1+oldLeading);
} while(--state.numBreaks > 0);
}
}
Expand Down Expand Up @@ -667,8 +671,8 @@ void GL_DrawText(const char* inString, int x, int y, compositefontid_t defFont,
for(; *end && *end != '{' && *end != '\n'; end++);
}

strncpy(temp, string, end - string);
temp[end - string] = 0;
strncpy(temp, string, MIN_OF(MAX_FRAGMENTLENGTH, end - string));
temp[MIN_OF(MAX_FRAGMENTLENGTH, end - string)] = '\0';

if(end && *end == '\n')
{
Expand Down Expand Up @@ -724,8 +728,11 @@ void GL_DrawText(const char* inString, int x, int y, compositefontid_t defFont,
}
else
{
if(strlen(temp) > 0)
lastLineHeight = GL_TextFragmentHeight(temp, state.font);

cx = (float) x;
cy += (float) GL_TextFragmentHeight(temp, state.font) * (1+state.leading) * state.scaleY;
cy += (float) lastLineHeight * (1+state.leading);
}

glMatrixMode(GL_MODELVIEW);
Expand All @@ -737,6 +744,7 @@ void GL_DrawText(const char* inString, int x, int y, compositefontid_t defFont,
if(bigBuff)
free(bigBuff);

#undef MAX_FRAGMENTLENGTH
#undef SMALLBUFF_SIZE
}

Expand Down
52 changes: 14 additions & 38 deletions doomsday/plugins/common/src/f_infine.c
Expand Up @@ -1169,7 +1169,7 @@ fipic_t* FI_GetPic(const char* handle)

fitext_t* FI_GetText(char* handle)
{
#define LEADING (1.5f)
#define LEADING (11.f/7-1)

fitext_t* unused = NULL;
int i;
Expand Down Expand Up @@ -1203,7 +1203,6 @@ fitext_t* FI_GetText(char* handle)
unused->wait = 3;
unused->font = GF_FONTA;
unused->lineheight = LEADING;
// Red text by default.
for(i = 0; i < 3; ++i)
FI_InitValue(&unused->object.color[i], defFontRGB2[i]);
FI_InitValue(&unused->object.color[CA], 1); // Opaque.
Expand Down Expand Up @@ -1472,22 +1471,8 @@ int FI_Responder(event_t* ev)
return FI_SkipRequest();
}

int FI_FilterChar(int ch)
{
// Filter it.
if(ch == '_')
ch = '[';
else if(ch == '\\')
ch = '/';
else if(ch < ' ' || ch > 'z')
ch = ' '; // We don't have this char.

return ch;
}

int FI_CharWidth(int ch, compositefontid_t font)
{
ch = FI_FilterChar(ch);
return GL_CharWidth(ch, font);
}

Expand All @@ -1514,13 +1499,6 @@ int FI_GetLineWidth(char* text, compositefontid_t font)
return width;
}

int FI_DrawChar(int x, int y, int ch, compositefontid_t font)
{
ch = FI_FilterChar(ch);
GL_DrawChar2(ch, x, y, font);
return FI_CharWidth(ch, font);
}

void FI_UseColor(fivalue_t *color, int components)
{
if(components == 3)
Expand Down Expand Up @@ -1590,25 +1568,23 @@ void FI_Rotate(float angle)
DGL_Scalef(1, 240.0f / 200.0f, 1);
}

void FI_DrawText(fitext_t *tex)
void FI_DrawText(fitext_t* tex)
{
int cnt, x = 0, y = 0;
char *ptr;
int linew = -1;
int ch;
int cnt, x = 0, y = 0;
int ch, linew = -1;
char* ptr;

DGL_MatrixMode(DGL_MODELVIEW);
DGL_PushMatrix();
DGL_Translatef(tex->object.x.value, tex->object.y.value, 0);

FI_Rotate(tex->object.angle.value);
DGL_Scalef(tex->object.scale[0].value, tex->object.scale[1].value, 1);

// Draw it.
// Set color zero (the normal color).
FI_UseTextColor(tex, 0);

// Draw it.
for(cnt = 0, ptr = tex->text; *ptr && (!tex->wait || cnt < tex->pos);
ptr++)
for(cnt = 0, ptr = tex->text; *ptr && (!tex->wait || cnt < tex->pos); ptr++)
{
if(linew < 0)
linew = FI_GetLineWidth(ptr, tex->font);
Expand All @@ -1630,15 +1606,15 @@ void FI_DrawText(fitext_t *tex)
if(*ptr == 'w' || *ptr == 'W') // Wait?
{
if(tex->wait)
cnt += (int) (35.0 / tex->wait / (*ptr == 'w' ? 2 : 1));
cnt += (int) ((float)TICRATE / tex->wait / (*ptr == 'w' ? 2 : 1));
continue;
}

// 'p' = 5 second wait, 'P' = 10 second wait
if(*ptr == 'p' || *ptr == 'P') // Longer pause?
{
if(tex->wait)
cnt += (int) (35.0 / tex->wait * (*ptr == 'p' ? 5 : 10));
cnt += (int) ((float)TICRATE / tex->wait * (*ptr == 'p' ? 5 : 10));
continue;
}

Expand All @@ -1656,11 +1632,11 @@ void FI_DrawText(fitext_t *tex)
}

// Let's do Y-clipping (in case of tall text blocks).
if(tex->object.scale[1].value * y + tex->object.y.value >=
-tex->object.scale[1].value * tex->lineheight &&
tex->object.scale[1].value * y + tex->object.y.value < 200)
if(tex->object.scale[1].value * y + tex->object.y.value >= -tex->object.scale[1].value * tex->lineheight &&
tex->object.scale[1].value * y + tex->object.y.value < SCREENHEIGHT)
{
x += FI_DrawChar(tex->flags.centered ? x - linew / 2 : x, y, ch, tex->font);
GL_DrawChar2(ch, tex->flags.centered ? x - linew / 2 : x, y, tex->font);
x += FI_CharWidth(ch, tex->font);
}

cnt++; // Actual character drawn.
Expand Down
4 changes: 2 additions & 2 deletions doomsday/plugins/common/src/hu_log.c
Expand Up @@ -414,7 +414,7 @@ void Hu_LogDrawer(int player, float textAlpha, float iconAlpha,
// Draw using param text.
// Messages may use the params to override the way the message is
// is displayed, e.g. colour (Hexen's important messages).
GL_DrawText(msg->text, 0, y, GF_FONTA, textFlags, 0, col[CR], col[CG], col[CB], col[CA], 0, 0, false);
GL_DrawText(msg->text, 0, y, GF_FONTA, textFlags, .5f, 0, col[CR], col[CG], col[CB], col[CA], 0, 0, false);

if(width > *drawnWidth)
*drawnWidth = width;
Expand Down Expand Up @@ -852,7 +852,7 @@ void Chat_Drawer(int player, float textAlpha, float iconAlpha,
xOffset = -GL_CharWidth('_', GF_FONTA);
}
textFlags = DTF_ALIGN_TOP|DTF_NO_EFFECTS | ((cfg.msgAlign == 0)? DTF_ALIGN_LEFT : (cfg.msgAlign == 2)? DTF_ALIGN_RIGHT : 0);
GL_DrawText(str, xOffset, 0, GF_FONTA, textFlags, 0, cfg.hudColor[CR], cfg.hudColor[CG], cfg.hudColor[CB], textAlpha, 0, 0, false);
GL_DrawText(str, xOffset, 0, GF_FONTA, textFlags, .5f, 0, cfg.hudColor[CR], cfg.hudColor[CG], cfg.hudColor[CB], textAlpha, 0, 0, false);
*drawnWidth = GL_TextWidth(chat->buffer.l.l, GF_FONTA) + GL_CharWidth('_', GF_FONTA);
*drawnHeight = MAX_OF(GL_TextHeight(chat->buffer.l.l, GF_FONTA), GL_CharHeight('_', GF_FONTA));
}
Expand Down
8 changes: 6 additions & 2 deletions doomsday/plugins/common/src/hu_msg.c
Expand Up @@ -187,6 +187,8 @@ static void composeYesNoMessage(void)

static void drawMessage(void)
{
#define LEADING (.5f)

int x = SCREENWIDTH/2, y = SCREENHEIGHT/2;
const char* questionString;

Expand All @@ -198,12 +200,14 @@ static void drawMessage(void)
Con_Error("drawMessage: Internal error, unknown message type %i.\n", (int) msgType);
}

GL_DrawText(msgText, x, y, GF_FONTA, DTF_ALIGN_TOP, 0, cfg.menuColor2[0], cfg.menuColor2[1], cfg.menuColor2[2], 1, cfg.menuGlitter, cfg.menuShadow, false);
GL_DrawText(msgText, x, y, GF_FONTA, DTF_ALIGN_TOP, LEADING, 0, cfg.menuColor2[0], cfg.menuColor2[1], cfg.menuColor2[2], 1, cfg.menuGlitter, cfg.menuShadow, false);
y += GL_TextHeight(msgText, GF_FONTA);
// An additional blank line between the message and response prompt.
y += GL_CharHeight('A', GF_FONTA);
y += GL_CharHeight('A', GF_FONTA) * (1+LEADING);

GL_DrawTextFragment7(questionString, x, y, GF_FONTA, DTF_ALIGN_TOP, 0, 0, cfg.menuGlitter, cfg.menuShadow);

#undef LEADING
}

/**
Expand Down
6 changes: 3 additions & 3 deletions doomsday/plugins/common/src/hu_stuff.c
Expand Up @@ -1200,7 +1200,7 @@ void WI_DrawPatch4(patchid_t patch, int x, int y, const char* altstring,
R_GetPatchInfo(patch, &info);
if(!info.isCustom)
{
GL_DrawText(altstring, x, y, font, translatePatchToTextDrawFlags(flags), 0, r, g, b, a, menu_glitter, menu_shadow, false);
GL_DrawText(altstring, x, y, font, translatePatchToTextDrawFlags(flags), .5f, 0, r, g, b, a, menu_glitter, menu_shadow, false);
return;
}
}
Expand Down Expand Up @@ -1230,14 +1230,14 @@ void WI_DrawPatch4(patchid_t patch, int x, int y, const char* altstring,
// A user replacement?
if(patchString)
{
GL_DrawText(string, x, y, font, textFlags, 0, r, g, b, a, menu_glitter, menu_shadow, false);
GL_DrawText(string, x, y, font, textFlags, .5f, 0, r, g, b, a, menu_glitter, menu_shadow, false);
return;
}

// A built-in replacement?
if(cfg.usePatchReplacement == 2 && altstring && altstring[0])
{
GL_DrawText(altstring, x, y, font, textFlags, 0, r, g, b, a, menu_glitter, menu_shadow, false);
GL_DrawText(altstring, x, y, font, textFlags, .5f, 0, r, g, b, a, menu_glitter, menu_shadow, false);
return;
}
}
Expand Down
2 changes: 1 addition & 1 deletion doomsday/plugins/jhexen/src/st_stuff.c
Expand Up @@ -2037,7 +2037,7 @@ void drawWorldTimerWidget(int player, float textAlpha, float iconAlpha,
strncat(buf2, "\nYOU FREAK!!!", 20);
strncat(buf, buf2, 60);
}
GL_DrawText(buf, 0, 0, GF_FONTA, DTF_ALIGN_TOPRIGHT|DTF_NO_EFFECTS, 0, 1, 1, 1, textAlpha, 0, 0, false);
GL_DrawText(buf, 0, 0, GF_FONTA, DTF_ALIGN_TOPRIGHT|DTF_NO_EFFECTS, .5f, 0, 1, 1, 1, textAlpha, 0, 0, false);

*drawnWidth = GL_TextWidth(buf, GF_FONTA);
*drawnHeight = GL_TextHeight(buf, GF_FONTA);
Expand Down

0 comments on commit aa73a58

Please sign in to comment.