[PATCH] sfnt2fon: Prevent reading past allocated buffer

Austin English austinenglish at gmail.com
Tue Jul 24 14:53:19 CDT 2018


On Tue, Jul 24, 2018 at 1:03 PM,  <janisozaur at gmail.com> wrote:
> 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.
> ---
>  tools/sfnt2fon/sfnt2fon.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
>
> diff --git a/tools/sfnt2fon/sfnt2fon.c b/tools/sfnt2fon/sfnt2fon.c
> index 25f0763872..fb125bbeaf 100644
> --- a/tools/sfnt2fon/sfnt2fon.c
> +++ b/tools/sfnt2fon/sfnt2fon.c
> @@ -570,11 +570,14 @@ static struct fontinfo *fill_fontinfo( const char *face_name, int ppem, int enc,
>                  else
>                      left_byte = face->glyph->bitmap.buffer[(y - (ascent - face->glyph->bitmap_top)) * face->glyph->bitmap.pitch + x - x_off - 1];
>
> +                int x_idx = (y - (ascent - face->glyph->bitmap_top)) * face->glyph->bitmap.pitch + x - x_off;
> +                // FreeType allocates that many bytes for bitmap, but some fonts (e.g. Courier) might try reading past the buffer
> +                int 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((x_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[x_idx];
>
>                  byte = (left_byte << (8 - (face->glyph->bitmap_left & 7))) & 0xff;
>                  byte |= ((right_byte >> (face->glyph->bitmap_left & 7)) & 0xff);
> --
> 2.18.0

Hi Michal,

Thanks for the patch. A couple things:
A) It's causing a warning when building:
sfnt2fon.c: In function 'fill_fontinfo':
sfnt2fon.c:573:17: warning: ISO C90 forbids mixed declarations and
code [-Wdeclaration-after-statement]
                 int x_idx = (y - (ascent - face->glyph->bitmap_top))
* face->glyph->bitmap.pitch + x - x_off;
                 ^~~
B) C++ style comments (//) aren't used in wine, please use C89 (/* comment */)

BTW, I thought that code looked familiar. It turns out this also fixes
a bug that AddressSanitizer/Valgrind report,
https://bugs.winehq.org/show_bug.cgi?id=45422. With it, I can build
wine's fonts under AddressSanitizer, thanks!

-- 
-Austin
GPG: 267B CC1F 053F 0749 (expires 2021/02/18)



More information about the wine-devel mailing list