Skip to content

Commit

Permalink
Merge pull request #2548 from REW1L/fix-issue-2543
Browse files Browse the repository at this point in the history
Fix issue #2543 segfault in font dealloc after reinit
  • Loading branch information
illume committed Oct 23, 2021
2 parents c19a66e + d495000 commit b72ba79
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 2 deletions.
14 changes: 12 additions & 2 deletions src_c/font.c
Expand Up @@ -65,6 +65,7 @@ PyFont_New(TTF_Font *);
#define PyFont_Check(x) ((x)->ob_type == &PyFont_Type)

static int font_initialized = 0;
static unsigned int current_ttf_generation = 0;
static const char font_defaultname[] = "freesansbold.ttf";
static const char pkgdatamodule_name[] = "pygame.pkgdata";
static const char resourcefunc_name[] = "getResource";
Expand Down Expand Up @@ -200,6 +201,7 @@ fontmodule_quit(PyObject *self)
if (font_initialized) {
TTF_Quit();
font_initialized = 0;
current_ttf_generation++;
}
Py_RETURN_NONE;
}
Expand Down Expand Up @@ -730,9 +732,16 @@ static void
font_dealloc(PyFontObject *self)
{
TTF_Font *font = PyFont_AsFont(self);

if (font && font_initialized)
if (font && font_initialized) {
if (self->ttf_init_generation != current_ttf_generation) {
// Since TTF_Font is a private structure
// it's impossible to access face field in a common way.
int** face_pp = font;
*face_pp = NULL;
}
TTF_CloseFont(font);
self->font = NULL;
}

if (self->weakreflist)
PyObject_ClearWeakRefs((PyObject *)self);
Expand Down Expand Up @@ -898,6 +907,7 @@ font_init(PyFontObject *self, PyObject *args, PyObject *kwds)
Py_XDECREF(oencoded);
Py_DECREF(obj);
self->font = font;
self->ttf_init_generation = current_ttf_generation;
return 0;

error:
Expand Down
1 change: 1 addition & 0 deletions src_c/include/pygame_font.h
Expand Up @@ -29,6 +29,7 @@ typedef struct {
PyObject_HEAD
TTF_Font* font;
PyObject* weakreflist;
unsigned int ttf_init_generation;
} PyFontObject;
#define PyFont_AsFont(x) (((PyFontObject*)x)->font)

Expand Down
10 changes: 10 additions & 0 deletions test/font_test.py
Expand Up @@ -206,6 +206,16 @@ def test_issue_font_alphablit(self):

self.assertEqual(pre_blit_corner_pixel, post_blit_corner_pixel)

def test_segfault_after_reinit(self):
""" Reinitialization of font module should not cause
segmentation fault """
import gc
font = pygame_font.Font(None, 20)
pygame_font.quit()
pygame_font.init()
del font
gc.collect()

def test_quit(self):
pygame_font.quit()

Expand Down

0 comments on commit b72ba79

Please sign in to comment.