Do not raise error if bitmap buffer is empty

This commit is contained in:
Andrew Murray 2024-08-23 18:24:04 +10:00
parent d6cfebd016
commit f9f7ba4ce9
2 changed files with 138 additions and 139 deletions

View File

@ -1,10 +1,8 @@
from __future__ import annotations from __future__ import annotations
import pytest
from PIL import Image, ImageDraw, ImageFont from PIL import Image, ImageDraw, ImageFont
from .helper import skip_unless_feature from .helper import skip_unless_feature_version
class TestFontCrash: class TestFontCrash:
@ -17,8 +15,7 @@ class TestFontCrash:
draw.multiline_textbbox((10, 10), "ABC\nAaaa", font, stroke_width=2) draw.multiline_textbbox((10, 10), "ABC\nAaaa", font, stroke_width=2)
draw.text((10, 10), "Test Text", font=font, fill="#000") draw.text((10, 10), "Test Text", font=font, fill="#000")
@skip_unless_feature("freetype2") @skip_unless_feature_version("freetype2", "2.12.0")
def test_segfault(self) -> None: def test_segfault(self) -> None:
with pytest.raises(OSError):
font = ImageFont.truetype("Tests/fonts/fuzz_font-5203009437302784") font = ImageFont.truetype("Tests/fonts/fuzz_font-5203009437302784")
self._fuzz_font(font) self._fuzz_font(font)

View File

@ -1025,12 +1025,7 @@ font_render(FontObject *self, PyObject *args) {
yy = -(py + glyph_slot->bitmap_top); yy = -(py + glyph_slot->bitmap_top);
} }
// Null buffer, is dereferenced in FT_Bitmap_Convert if (bitmap.buffer) {
if (!bitmap.buffer && bitmap.rows) {
PyErr_SetString(PyExc_OSError, "Bitmap missing for glyph");
goto glyph_error;
}
/* convert non-8bpp bitmaps */ /* convert non-8bpp bitmaps */
switch (bitmap.pixel_mode) { switch (bitmap.pixel_mode) {
case FT_PIXEL_MODE_MONO: case FT_PIXEL_MODE_MONO:
@ -1115,15 +1110,20 @@ font_render(FontObject *self, PyObject *args) {
/* blend required if target has data */ /* blend required if target has data */
if (target[k * 4 + 3] > 0) { if (target[k * 4 + 3] > 0) {
/* blend RGBA colors */ /* blend RGBA colors */
target[k * 4 + 0] = target[k * 4 + 0] = BLEND(
BLEND(src_alpha, target[k * 4 + 0], src_red, tmp); src_alpha, target[k * 4 + 0], src_red, tmp
target[k * 4 + 1] = );
BLEND(src_alpha, target[k * 4 + 1], src_green, tmp); target[k * 4 + 1] = BLEND(
target[k * 4 + 2] = src_alpha, target[k * 4 + 1], src_green, tmp
BLEND(src_alpha, target[k * 4 + 2], src_blue, tmp); );
target[k * 4 + 2] = BLEND(
src_alpha, target[k * 4 + 2], src_blue, tmp
);
target[k * 4 + 3] = CLIP8( target[k * 4 + 3] = CLIP8(
src_alpha + src_alpha +
MULDIV255(target[k * 4 + 3], (255 - src_alpha), tmp) MULDIV255(
target[k * 4 + 3], (255 - src_alpha), tmp
)
); );
} else { } else {
/* paste unpremultiplied RGBA values */ /* paste unpremultiplied RGBA values */
@ -1151,9 +1151,10 @@ font_render(FontObject *self, PyObject *args) {
src_alpha, target[k * 4 + 2], ink[2], tmp src_alpha, target[k * 4 + 2], ink[2], tmp
); );
target[k * 4 + 3] = CLIP8( target[k * 4 + 3] = CLIP8(
src_alpha + src_alpha + MULDIV255(
MULDIV255( target[k * 4 + 3],
target[k * 4 + 3], (255 - src_alpha), tmp (255 - src_alpha),
tmp
) )
); );
} else { } else {
@ -1187,6 +1188,7 @@ font_render(FontObject *self, PyObject *args) {
} }
source += bitmap.pitch; source += bitmap.pitch;
} }
}
x += glyph_info[i].x_advance; x += glyph_info[i].x_advance;
y += glyph_info[i].y_advance; y += glyph_info[i].y_advance;
if (stroker != NULL) { if (stroker != NULL) {