Fix game crashing if using default.png with width < 16 or non power of two

This commit is contained in:
UnknownShadow200 2020-04-20 22:47:22 +10:00
parent feff50b4c4
commit d64d0eb9e1
3 changed files with 25 additions and 9 deletions

View File

@ -109,9 +109,6 @@ static void CalculateTextWidths(void) {
BitmapCol* row; BitmapCol* row;
int i, x, y, xx, tileX, tileY; int i, x, y, xx, tileX, tileY;
/* If 128x256 font bitmap is supplied, treat it as 128x128 */
height = min(width, height);
for (y = 0; y < height; y++) { for (y = 0; y < height; y++) {
tileY = y / tileSize; tileY = y / tileSize;
row = Bitmap_GetRow(&fontBitmap, y); row = Bitmap_GetRow(&fontBitmap, y);
@ -139,11 +136,27 @@ static void FreeFontBitmap(void) {
Mem_Free(fontBitmap.Scan0); Mem_Free(fontBitmap.Scan0);
} }
void Drawer2D_SetFontBitmap(Bitmap* bmp) { cc_bool Drawer2D_SetFontBitmap(Bitmap* bmp) {
/* If all these cases are not accounted for, end up overwriting memory after tileWidths */
if (bmp->Width != bmp->Height) {
static const String msg = String_FromConst("&cWidth of default.png must equal its height");
Logger_WarnFunc(&msg);
return false;
} else if (bmp->Width < 16) {
static const String msg = String_FromConst("&cdefault.png must be at least 16 pixels wide");
Logger_WarnFunc(&msg);
return false;
} else if (!Math_IsPowOf2(bmp->Width)) {
static const String msg = String_FromConst("&cWidth of default.png must be a power of two");
Logger_WarnFunc(&msg);
return false;
}
FreeFontBitmap(); FreeFontBitmap();
fontBitmap = *bmp; fontBitmap = *bmp;
tileSize = bmp->Width >> LOG2_CHARS_PER_ROW; tileSize = bmp->Width >> LOG2_CHARS_PER_ROW;
CalculateTextWidths(); CalculateTextWidths();
return true;
} }
void Font_ReducePadding(struct FontDesc* desc, int scale) { void Font_ReducePadding(struct FontDesc* desc, int scale) {
@ -683,9 +696,10 @@ static void OnFileChanged(void* obj, struct Stream* src, const String* name) {
if ((res = Png_Decode(&bmp, src))) { if ((res = Png_Decode(&bmp, src))) {
Logger_Warn2(res, "decoding", name); Logger_Warn2(res, "decoding", name);
Mem_Free(bmp.Scan0); Mem_Free(bmp.Scan0);
} else { } else if (Drawer2D_SetFontBitmap(&bmp)) {
Drawer2D_SetFontBitmap(&bmp);
Event_RaiseVoid(&ChatEvents.FontChanged); Event_RaiseVoid(&ChatEvents.FontChanged);
} else {
Mem_Free(bmp.Scan0);
} }
} }

View File

@ -93,7 +93,7 @@ void Drawer2D_ReducePadding_Tex(struct Texture* tex, int point, int scale);
void Drawer2D_ReducePadding_Height(int* height, int point, int scale); void Drawer2D_ReducePadding_Height(int* height, int point, int scale);
/* Sets the bitmap used for drawing bitmapped fonts. (i.e. default.png) */ /* Sets the bitmap used for drawing bitmapped fonts. (i.e. default.png) */
/* The bitmap must be square and consist of a 16x16 tile layout. */ /* The bitmap must be square and consist of a 16x16 tile layout. */
void Drawer2D_SetFontBitmap(Bitmap* bmp); cc_bool Drawer2D_SetFontBitmap(Bitmap* bmp);
/* Gets the list of all supported system font names on this platform. */ /* Gets the list of all supported system font names on this platform. */
void Font_GetNames(StringsBuffer* buffer); void Font_GetNames(StringsBuffer* buffer);

View File

@ -391,9 +391,11 @@ static cc_result Launcher_ProcessZipEntry(const String* path, struct Stream* dat
if (res) { if (res) {
Logger_Warn(res, "decoding default.png"); return res; Logger_Warn(res, "decoding default.png"); return res;
} else { } else if (Drawer2D_SetFontBitmap(&fontBmp)) {
Drawer2D_SetFontBitmap(&fontBmp);
useBitmappedFont = !Options_GetBool(OPT_USE_CHAT_FONT, false); useBitmappedFont = !Options_GetBool(OPT_USE_CHAT_FONT, false);
} else {
Mem_Free(fontBmp.Scan0);
fontBmp.Scan0 = NULL;
} }
} else if (String_CaselessEqualsConst(path, "terrain.png")) { } else if (String_CaselessEqualsConst(path, "terrain.png")) {
if (dirtBmp.Scan0) return 0; if (dirtBmp.Scan0) return 0;