Browse Source

Some security checks on font loading

Ray 6 years ago
parent
commit
3b674cd281
1 changed files with 82 additions and 80 deletions
  1. 82 80
      src/text.c

+ 82 - 80
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;
 }