[PATCH v2] sfnt2fon: Prevent reading past allocated buffer

janisozaur at gmail.com janisozaur at gmail.com
Tue Jul 24 15:28:34 CDT 2018


From: MichaƂ Janiszewski <janisozaur at gmail.com>

Some fonts (e.g. Courier) may cause sfnt2fon try reading past end of
heap-allocated buffer. Rather than reading from uninitialised memory,
return 0 in such case.

Visual tests on .fon render of this font (using FontForge) shown no
artifacts.

This should fix Bug 45422

v2:
- Improve C89 compatibility
- Use cached index for both left and right bytes
---
 tools/sfnt2fon/sfnt2fon.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/tools/sfnt2fon/sfnt2fon.c b/tools/sfnt2fon/sfnt2fon.c
index 25f0763872..0f788da7e1 100644
--- a/tools/sfnt2fon/sfnt2fon.c
+++ b/tools/sfnt2fon/sfnt2fon.c
@@ -554,6 +554,7 @@ static struct fontinfo *fill_fontinfo( const char *face_name, int ppem, int enc,
 
         for(x = 0; x < ((info->dfCharTable[i].width + 7) / 8); x++) {
             for(y = 0; y < ppem; y++) {
+                int idx, x_limit;
                 if(y < ascent - face->glyph->bitmap_top ||
                    y >=  face->glyph->bitmap.rows + ascent - face->glyph->bitmap_top) {
                     info->data[data_pos++] = 0;
@@ -565,16 +566,19 @@ static struct fontinfo *fill_fontinfo( const char *face_name, int ppem, int enc,
                     info->data[data_pos++] = 0;
                     continue;
                 }
+                idx = (y - (ascent - face->glyph->bitmap_top)) * face->glyph->bitmap.pitch + x - x_off;
                 if(x == x_off)
                     left_byte = 0;
                 else
-                    left_byte = face->glyph->bitmap.buffer[(y - (ascent - face->glyph->bitmap_top)) * face->glyph->bitmap.pitch + x - x_off - 1];
+                    left_byte = face->glyph->bitmap.buffer[idx - 1];
 
+                /* FreeType allocates that many bytes for bitmap, but some fonts (e.g. Courier) might try reading past the buffer */
+                x_limit = face->glyph->bitmap.rows * face->glyph->bitmap.pitch;
                 /* On the last non-trivial output byte (x == x_end) have we got one or two input bytes */
-                if(x == x_end && (face->glyph->bitmap_left % 8 != 0) && ((face->glyph->bitmap.width % 8 == 0) || (x != (((face->glyph->bitmap.width) & ~0x7) + face->glyph->bitmap_left) / 8)))
+                if((idx >= x_limit) || (x == x_end && (face->glyph->bitmap_left % 8 != 0) && ((face->glyph->bitmap.width % 8 == 0) || (x != (((face->glyph->bitmap.width) & ~0x7) + face->glyph->bitmap_left) / 8))))
                     right_byte = 0;
                 else
-                    right_byte = face->glyph->bitmap.buffer[(y - (ascent - face->glyph->bitmap_top)) * face->glyph->bitmap.pitch + x - x_off];
+                    right_byte = face->glyph->bitmap.buffer[idx];
 
                 byte = (left_byte << (8 - (face->glyph->bitmap_left & 7))) & 0xff;
                 byte |= ((right_byte >> (face->glyph->bitmap_left & 7)) & 0xff);
-- 
2.18.0




More information about the wine-devel mailing list