Browse Source

Check for buffer overflows in the glyph atlas

rexim 2 years ago
parent
commit
58736a6630
4 changed files with 19 additions and 4 deletions
  1. 12 2
      src/free_glyph.c
  2. 3 1
      src/free_glyph.h
  3. 3 1
      src/main.c
  4. 1 0
      src/simple_renderer.c

+ 12 - 2
src/free_glyph.c

@@ -79,7 +79,12 @@ float free_glyph_atlas_cursor_pos(const Free_Glyph_Atlas *atlas, const char *tex
             return pos.x;
         }
 
-        Glyph_Metric metric = atlas->metrics[(int) text[i]];
+        size_t glyph_index = text[i];
+        if (glyph_index >= GLYPH_METRICS_CAPACITY) {
+            glyph_index = '?';
+        }
+
+        Glyph_Metric metric = atlas->metrics[glyph_index];
         pos.x += metric.ax;
         pos.y += metric.ay;
     }
@@ -90,7 +95,12 @@ float free_glyph_atlas_cursor_pos(const Free_Glyph_Atlas *atlas, const char *tex
 void free_glyph_atlas_render_line_sized(Free_Glyph_Atlas *atlas, Simple_Renderer *sr, const char *text, size_t text_size, Vec2f *pos, bool render)
 {
     for (size_t i = 0; i < text_size; ++i) {
-        Glyph_Metric metric = atlas->metrics[(int) text[i]];
+        size_t glyph_index = text[i];
+        // TODO: support for glyphs outside of ASCII range
+        if (glyph_index >= GLYPH_METRICS_CAPACITY) {
+            glyph_index = '?';
+        }
+        Glyph_Metric metric = atlas->metrics[glyph_index];
         float x2 = pos->x + metric.bl;
         float y2 = -pos->y - metric.bt;
         float w  = metric.bw;

+ 3 - 1
src/free_glyph.h

@@ -30,11 +30,13 @@ typedef struct {
     float tx; // x offset of glyph in texture coordinates
 } Glyph_Metric;
 
+#define GLYPH_METRICS_CAPACITY 128
+
 typedef struct {
     FT_UInt atlas_width;
     FT_UInt atlas_height;
     GLuint glyphs_texture;
-    Glyph_Metric metrics[128];
+    Glyph_Metric metrics[GLYPH_METRICS_CAPACITY];
 } Free_Glyph_Atlas;
 
 void free_glyph_atlas_init(Free_Glyph_Atlas *atlas, FT_Face face);

+ 3 - 1
src/main.c

@@ -362,8 +362,10 @@ int main(int argc, char **argv)
 
                     case SDLK_RETURN: {
                         if (fb.cursor < fb.files.count) {
-                            // TODO: go into folders
+                            // TODO: go inside folders
                             const char *file_path = fb.files.items[fb.cursor];
+                            // TODO: before opening a new file make sure you don't have unsaved changes
+                            // And if you do, annoy the user about it. (just like all the other editors do)
                             err = editor_load_from_file(&editor, file_path);
                             if (err != 0) {
                                 flash_error("Could not open file %s: %s", file_path, strerror(err));

+ 1 - 0
src/simple_renderer.c

@@ -213,6 +213,7 @@ void simple_renderer_init(Simple_Renderer *sr,
 void simple_renderer_vertex(Simple_Renderer *sr,
                             Vec2f p, Vec4f c, Vec2f uv)
 {
+    // TODO: flush the renderer on vertex buffer overflow instead firing the assert
     assert(sr->verticies_count < SIMPLE_VERTICIES_CAP);
     Simple_Vertex *last = &sr->verticies[sr->verticies_count];
     last->position = p;