From bb7124325ef1851762ba709877a28057f361a36e Mon Sep 17 00:00:00 2001 From: wiredfool Date: Thu, 31 Aug 2017 08:52:29 -0700 Subject: [PATCH 1/3] Don't return null on empty string --- _imagingft.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_imagingft.c b/_imagingft.c index 21188996d..7534e0bbb 100644 --- a/_imagingft.c +++ b/_imagingft.c @@ -585,7 +585,7 @@ font_render(FontObject* self, PyObject* args) glyph_info = NULL; count = text_layout(string, self, dir, features, &glyph_info, mask); if (count == 0) { - return NULL; + Py_RETURN_NONE; } im = (Imaging) id; From c3fbd9de01c936696cde6bf85f314f5456d1d27d Mon Sep 17 00:00:00 2001 From: wiredfool Date: Thu, 31 Aug 2017 08:56:06 -0700 Subject: [PATCH 2/3] test for issue #2666 --- Tests/test_imagefont.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 9f159e9e0..c3bc9ba35 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -404,10 +404,24 @@ class TestImageFont(PillowTestCase): self.assert_image_equal(im, target_img) def test_getsize_empty(self): + # issue #2614 font = self.get_font() # should not crash. self.assertEqual((0, 0), font.getsize('')) + def test_render_empty(self): + # issue 2666 + font = self.get_font() + im = Image.new(mode='RGB', size=(300, 100)) + target = im.copy() + draw = ImageDraw.Draw(im) + #should not crash here. + draw.text((10, 10), '', font=font) + self.assert_image_equal(im, target) + + + + def _test_fake_loading_font(self, path_to_fake, fontname): # Make a copy of FreeTypeFont so we can patch the original free_type_font = copy.deepcopy(ImageFont.FreeTypeFont) From ee430550eb74f0d819adffdd028198663ddadbe9 Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Thu, 31 Aug 2017 19:31:05 +0000 Subject: [PATCH 3/3] fix raqm with 0 length strings --- _imagingft.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/_imagingft.c b/_imagingft.c index 7534e0bbb..0cddc15cf 100644 --- a/_imagingft.c +++ b/_imagingft.c @@ -225,6 +225,11 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, if (PyUnicode_Check(string)) { Py_UNICODE *text = PyUnicode_AS_UNICODE(string); Py_ssize_t size = PyUnicode_GET_SIZE(string); + if (! size) { + /* return 0 and clean up, no glyphs==no size, + and raqm fails with empty strings */ + goto failed; + } if (!raqm_set_text(rq, (const uint32_t *)(text), size)) { PyErr_SetString(PyExc_ValueError, "raqm_set_text() failed"); goto failed; @@ -234,6 +239,9 @@ text_layout_raqm(PyObject* string, FontObject* self, const char* dir, else if (PyString_Check(string)) { char *text = PyString_AS_STRING(string); int size = PyString_GET_SIZE(string); + if (! size) { + goto failed; + } if (!raqm_set_text_utf8(rq, text, size)) { PyErr_SetString(PyExc_ValueError, "raqm_set_text_utf8() failed"); goto failed; @@ -450,6 +458,10 @@ font_getsize(FontObject* self, PyObject* args) y_max = y_min = 0; count = text_layout(string, self, dir, features, &glyph_info, 0); + if (PyErr_Occurred()) { + return NULL; + } + for (x = i = 0; i < count; i++) { int index, error; @@ -584,6 +596,9 @@ font_render(FontObject* self, PyObject* args) glyph_info = NULL; count = text_layout(string, self, dir, features, &glyph_info, mask); + if (PyErr_Occurred()) { + return NULL; + } if (count == 0) { Py_RETURN_NONE; }