aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2018-10-18 17:48:33 +0200
committerRay <raysan5@gmail.com>2018-10-18 17:48:33 +0200
commit3b674cd2810499d05a8edb0a7392cb90d0b95e3f (patch)
tree129548685d554d09585552d835b52ac79095fbfc
parent764766bfb2160cdbe3196abe3c90ad86197fc8d6 (diff)
downloadraylib-3b674cd2810499d05a8edb0a7392cb90d0b95e3f.tar.gz
raylib-3b674cd2810499d05a8edb0a7392cb90d0b95e3f.zip
Some security checks on font loading
-rw-r--r--src/text.c162
1 files changed, 82 insertions, 80 deletions
diff --git a/src/text.c b/src/text.c
index 5d5de6fa..51e93b72 100644
--- a/src/text.c
+++ b/src/text.c
@@ -276,15 +276,7 @@ Font LoadFont(const char *fileName)
Font font = { 0 };
#if defined(SUPPORT_FILEFORMAT_TTF)
- if (IsFileExtension(fileName, ".ttf"))
- {
- font.baseSize = DEFAULT_TTF_FONTSIZE;
- font.charsCount = DEFAULT_TTF_NUMCHARS;
- font.chars = LoadFontData(fileName, font.baseSize, NULL, font.charsCount, FONT_DEFAULT);
- Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 4, 0);
- font.texture = LoadTextureFromImage(atlas);
- UnloadImage(atlas);
- }
+ if (IsFileExtension(fileName, ".ttf")) font = LoadFontEx(fileName, DEFAULT_TTF_FONTSIZE, DEFAULT_TTF_NUMCHARS, NULL);
else
#endif
#if defined(SUPPORT_FILEFORMAT_FNT)
@@ -317,9 +309,13 @@ Font LoadFontEx(const char *fileName, int fontSize, int charsCount, int *fontCha
font.baseSize = fontSize;
font.charsCount = (charsCount > 0) ? charsCount : 95;
font.chars = LoadFontData(fileName, font.baseSize, fontChars, font.charsCount, FONT_DEFAULT);
- Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 2, 0);
- font.texture = LoadTextureFromImage(atlas);
- UnloadImage(atlas);
+
+ if (font.chars != NULL)
+ {
+ Image atlas = GenImageFontAtlas(font.chars, font.charsCount, font.baseSize, 2, 0);
+ font.texture = LoadTextureFromImage(atlas);
+ UnloadImage(atlas);
+ }
return font;
}
@@ -335,91 +331,97 @@ CharInfo *LoadFontData(const char *fileName, int fontSize, int *fontChars, int c
#define SDF_PIXEL_DIST_SCALE 64.0f
#define BITMAP_ALPHA_THRESHOLD 80
-
- // In case no chars count provided, default to 95
- charsCount = (charsCount > 0) ? charsCount : 95;
-
- CharInfo *chars = (CharInfo *)malloc(charsCount*sizeof(CharInfo));
+
+ CharInfo *chars = NULL;
// Load font data (including pixel data) from TTF file
// NOTE: Loaded information should be enough to generate font image atlas,
// using any packaging method
FILE *fontFile = fopen(fileName, "rb"); // Load font file
- fseek(fontFile, 0, SEEK_END);
- long size = ftell(fontFile); // Get file size
- fseek(fontFile, 0, SEEK_SET); // Reset file pointer
-
- unsigned char *fontBuffer = (unsigned char *)malloc(size);
-
- fread(fontBuffer, size, 1, fontFile);
- fclose(fontFile);
-
- // Init font for data reading
- stbtt_fontinfo fontInfo;
- if (!stbtt_InitFont(&fontInfo, fontBuffer, 0)) TraceLog(LOG_WARNING, "Failed to init font!");
+ if (fontFile != NULL)
+ {
+ fseek(fontFile, 0, SEEK_END);
+ long size = ftell(fontFile); // Get file size
+ fseek(fontFile, 0, SEEK_SET); // Reset file pointer
+
+ unsigned char *fontBuffer = (unsigned char *)malloc(size);
+
+ fread(fontBuffer, size, 1, fontFile);
+ fclose(fontFile);
+
+ // Init font for data reading
+ stbtt_fontinfo fontInfo;
+ if (!stbtt_InitFont(&fontInfo, fontBuffer, 0)) TraceLog(LOG_WARNING, "Failed to init font!");
- // Calculate font scale factor
- float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize);
+ // Calculate font scale factor
+ float scaleFactor = stbtt_ScaleForPixelHeight(&fontInfo, (float)fontSize);
- // Calculate font basic metrics
- // NOTE: ascent is equivalent to font baseline
- int ascent, descent, lineGap;
- stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
-
- // Fill fontChars in case not provided externally
- // NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
- int genFontChars = false;
- if (fontChars == NULL) genFontChars = true;
- if (genFontChars)
- {
- fontChars = (int *)malloc(charsCount*sizeof(int));
- for (int i = 0; i < charsCount; i++) fontChars[i] = i + 32;
- }
-
- // NOTE: Using simple packaging, one char after another
- for (int i = 0; i < charsCount; i++)
- {
- int chw = 0, chh = 0; // Character width and height (on generation)
- int ch = fontChars[i]; // Character value to get info for
- chars[i].value = ch;
+ // Calculate font basic metrics
+ // NOTE: ascent is equivalent to font baseline
+ int ascent, descent, lineGap;
+ stbtt_GetFontVMetrics(&fontInfo, &ascent, &descent, &lineGap);
- // Render a unicode codepoint to a bitmap
- // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
- // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
- // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
+ // In case no chars count provided, default to 95
+ charsCount = (charsCount > 0) ? charsCount : 95;
- if (type != FONT_SDF) chars[i].data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
- else if (ch != 32) chars[i].data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
+ // Fill fontChars in case not provided externally
+ // NOTE: By default we fill charsCount consecutevely, starting at 32 (Space)
+ int genFontChars = false;
+ if (fontChars == NULL) genFontChars = true;
+ if (genFontChars)
+ {
+ fontChars = (int *)malloc(charsCount*sizeof(int));
+ for (int i = 0; i < charsCount; i++) fontChars[i] = i + 32;
+ }
+
+ chars = (CharInfo *)malloc(charsCount*sizeof(CharInfo));
- if (type == FONT_BITMAP)
+ // NOTE: Using simple packaging, one char after another
+ for (int i = 0; i < charsCount; i++)
{
- // Aliased bitmap (black & white) font generation, avoiding anti-aliasing
- // NOTE: For optimum results, bitmap font should be generated at base pixel size
- for (int p = 0; p < chw*chh; p++)
+ int chw = 0, chh = 0; // Character width and height (on generation)
+ int ch = fontChars[i]; // Character value to get info for
+ chars[i].value = ch;
+
+ // Render a unicode codepoint to a bitmap
+ // stbtt_GetCodepointBitmap() -- allocates and returns a bitmap
+ // stbtt_GetCodepointBitmapBox() -- how big the bitmap must be
+ // stbtt_MakeCodepointBitmap() -- renders into bitmap you provide
+
+ if (type != FONT_SDF) chars[i].data = stbtt_GetCodepointBitmap(&fontInfo, scaleFactor, scaleFactor, ch, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
+ else if (ch != 32) chars[i].data = stbtt_GetCodepointSDF(&fontInfo, scaleFactor, ch, SDF_CHAR_PADDING, SDF_ON_EDGE_VALUE, SDF_PIXEL_DIST_SCALE, &chw, &chh, &chars[i].offsetX, &chars[i].offsetY);
+
+ if (type == FONT_BITMAP)
{
- if (chars[i].data[p] < BITMAP_ALPHA_THRESHOLD) chars[i].data[p] = 0;
- else chars[i].data[p] = 255;
+ // Aliased bitmap (black & white) font generation, avoiding anti-aliasing
+ // NOTE: For optimum results, bitmap font should be generated at base pixel size
+ for (int p = 0; p < chw*chh; p++)
+ {
+ if (chars[i].data[p] < BITMAP_ALPHA_THRESHOLD) chars[i].data[p] = 0;
+ else chars[i].data[p] = 255;
+ }
}
- }
-
- chars[i].rec.width = (float)chw;
- chars[i].rec.height = (float)chh;
- chars[i].offsetY += (int)((float)ascent*scaleFactor);
-
- // Get bounding box for character (may be offset to account for chars that dip above or below the line)
- int chX1, chY1, chX2, chY2;
- stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
+
+ chars[i].rec.width = (float)chw;
+ chars[i].rec.height = (float)chh;
+ chars[i].offsetY += (int)((float)ascent*scaleFactor);
- TraceLog(LOG_DEBUG, "Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
- TraceLog(LOG_DEBUG, "Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
+ // Get bounding box for character (may be offset to account for chars that dip above or below the line)
+ int chX1, chY1, chX2, chY2;
+ stbtt_GetCodepointBitmapBox(&fontInfo, ch, scaleFactor, scaleFactor, &chX1, &chY1, &chX2, &chY2);
+
+ TraceLog(LOG_DEBUG, "Character box measures: %i, %i, %i, %i", chX1, chY1, chX2 - chX1, chY2 - chY1);
+ TraceLog(LOG_DEBUG, "Character offsetY: %i", (int)((float)ascent*scaleFactor) + chY1);
- stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
- chars[i].advanceX *= scaleFactor;
+ stbtt_GetCodepointHMetrics(&fontInfo, ch, &chars[i].advanceX, NULL);
+ chars[i].advanceX *= scaleFactor;
+ }
+
+ free(fontBuffer);
+ if (genFontChars) free(fontChars);
}
-
- free(fontBuffer);
- if (genFontChars) free(fontChars);
+ else TraceLog(LOG_WARNING, "[%s] TTF file could not be opened", fileName);
return chars;
}