From 3f4abf6caa2dcb8373f789e97f82ef13f5d4aa52 Mon Sep 17 00:00:00 2001 From: Eric Soroos Date: Thu, 2 Nov 2017 20:46:17 +0000 Subject: [PATCH] Fix/test for #2826, unchecked exception leading to null pointer dereference, segfault --- Tests/test_imagefont.py | 10 ++++++++-- _imaging.c | 13 +++++++++---- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/Tests/test_imagefont.py b/Tests/test_imagefont.py index 68757ff3f..c437e76b2 100644 --- a/Tests/test_imagefont.py +++ b/Tests/test_imagefont.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from helper import unittest, PillowTestCase from PIL import Image, ImageDraw, ImageFont, features @@ -409,8 +410,13 @@ class TestImageFont(PillowTestCase): draw.text((10, 10), '', font=font) self.assert_image_equal(im, target) - - + def test_unicode_pilfont(self): + # should not segfault, should return UnicodeDecodeError + # issue #2826 + font = ImageFont.load_default() + with self.assertRaises(UnicodeEncodeError): + font.getsize(u"’") + def _test_fake_loading_font(self, path_to_fake, fontname): # Make a copy of FreeTypeFont so we can patch the original diff --git a/_imaging.c b/_imaging.c index 8d97dd110..421bb5df4 100644 --- a/_imaging.c +++ b/_imaging.c @@ -2207,6 +2207,9 @@ void _font_text_asBytes(PyObject* encoded_string, unsigned char** text){ if (PyUnicode_CheckExact(encoded_string)){ bytes = PyUnicode_AsLatin1String(encoded_string); + if (!bytes) { + return; + } PyBytes_AsStringAndSize(bytes, &buffer, &len); } else if (PyBytes_Check(encoded_string)) { PyBytes_AsStringAndSize(encoded_string, &buffer, &len); @@ -2215,13 +2218,15 @@ void _font_text_asBytes(PyObject* encoded_string, unsigned char** text){ *text = calloc(len+1,1); if (*text) { memcpy(*text, buffer, len); + } else { + ImagingError_MemoryError(); } - if(bytes) { + if (bytes) { Py_DECREF(bytes); } return; - + /* UNDONE not reachable code */ #if PY_VERSION_HEX < 0x03000000 /* likely case here is py2.x with an ordinary string. @@ -2231,6 +2236,8 @@ void _font_text_asBytes(PyObject* encoded_string, unsigned char** text){ *text = calloc(len,1); if (*text) { memcpy(*text, buffer, len+1); + } else { + ImagingError_MemoryError(); } return; } @@ -2260,7 +2267,6 @@ _font_getmask(ImagingFontObject* self, PyObject* args) _font_text_asBytes(encoded_string, &text); if (!text) { - ImagingError_MemoryError(); return NULL; } @@ -2314,7 +2320,6 @@ _font_getsize(ImagingFontObject* self, PyObject* args) _font_text_asBytes(encoded_string, &text); if (!text) { - ImagingError_MemoryError(); return NULL; }