Skip to content

Commit cda7fea

Browse files
committed
Fix memory management
1 parent 3b8c127 commit cda7fea

File tree

7 files changed

+81
-51
lines changed

7 files changed

+81
-51
lines changed

src/bitmap.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ static void
6363
Py_Bitmap_dealloc(Py_Bitmap* self)
6464
{
6565
FT_Bitmap_Done(get_ft_library(), self->x);
66-
free(self->x);
66+
Py_TYPE(self)->tp_clear((PyObject*)self);
6767
Py_TYPE(self)->tp_free((PyObject*)self);
6868
}
6969

src/face.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,7 @@ Py_Face_dealloc(Py_Face* self)
239239
FT_Done_Face(self->x);
240240
Py_XDECREF(self->filename);
241241
free(self->mem);
242+
Py_TYPE(self)->tp_clear((PyObject*)self);
242243
Py_TYPE(self)->tp_free((PyObject*)self);
243244
}
244245

@@ -252,7 +253,8 @@ Py_Face_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
252253
if (self == NULL) {
253254
return NULL;
254255
}
255-
self->base.owner = NULL;
256+
Py_INCREF(freetypy_module);
257+
self->base.owner = freetypy_module;
256258
self->x = NULL;
257259
memset(&self->stream, 0, sizeof(FT_StreamRec));
258260
self->mem = NULL;
@@ -288,6 +290,14 @@ Py_Face_init(Py_Face *self, PyObject *args, PyObject *kwds)
288290
goto exit;
289291
}
290292

293+
if (open_args.stream != NULL) {
294+
self->x->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
295+
}
296+
297+
if (ftpy_exc(FT_Set_Char_Size(self->x, 12 * 64, 12 * 64, 72, 72))) {
298+
goto exit;
299+
}
300+
291301
Py_INCREF(py_file_arg);
292302
self->filename = py_file_arg;
293303

@@ -967,7 +977,7 @@ Py_Face_set_charmap(Py_Face* self, PyObject* args, PyObject* kwds) {
967977
return NULL;
968978
}
969979

970-
if (map > self->x->num_charmaps) {
980+
if (map > (unsigned long)self->x->num_charmaps) {
971981
PyErr_Format(
972982
PyExc_ValueError,
973983
"%lu is greater than the number of charmaps in the face (%d)",

src/freetypy.c

Lines changed: 37 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,9 @@ static PyMethodDef module_methods[] = {
7171
};
7272

7373

74+
PyObject *freetypy_module;
75+
76+
7477
/* TODO: Hide all exported symbols in the shared library except this one */
7578

7679
#if PY3K
@@ -103,21 +106,19 @@ static PyMethodDef module_methods[] = {
103106
init_freetypy(void)
104107
#endif
105108
{
106-
PyObject* m;
107-
108109
if (ftpy_exc(FT_Init_FreeType(&ft_library))) {
109110
INITERROR;
110111
}
111112

112113
#if PY3K
113-
m = PyModule_Create(&moduledef);
114+
freetypy_module = PyModule_Create(&moduledef);
114115
#else
115-
m = Py_InitModule3(
116+
freetypy_module = Py_InitModule3(
116117
"_freetypy", module_methods,
117118
"Freetype bindings");
118119
#endif
119120

120-
if (m == NULL) {
121+
if (freetypy_module == NULL) {
121122
INITERROR;
122123
}
123124

@@ -127,44 +128,45 @@ static PyMethodDef module_methods[] = {
127128

128129
FT_Library_Version(ft_library, &major, &minor, &patch);
129130
sprintf(version_string, "%d.%d.%d", major, minor, patch);
130-
if (PyModule_AddStringConstant(m, "__freetype_version__", version_string)) {
131+
if (PyModule_AddStringConstant(
132+
freetypy_module, "__freetype_version__", version_string)) {
131133
INITERROR;
132134
}
133135
}
134136

135-
if (setup_pyutil(m) ||
136-
setup_constants(m) ||
137-
setup_version(m) ||
137+
if (setup_pyutil(freetypy_module) ||
138+
setup_constants(freetypy_module) ||
139+
setup_version(freetypy_module) ||
138140
setup_errors() ||
139-
setup_BBox(m) ||
140-
setup_Bitmap(m) ||
141-
setup_Bitmap_Size(m) ||
142-
setup_CharIter(m) ||
143-
setup_CharMap(m) ||
144-
setup_Face(m) ||
145-
setup_Glyph(m) ||
146-
setup_Glyph_Metrics(m) ||
147-
setup_Layout(m) ||
148-
setup_Matrix(m) ||
149-
setup_Outline(m) ||
150-
setup_SfntName(m) ||
151-
setup_SfntNames(m) ||
152-
setup_Size(m) ||
153-
setup_Size_Metrics(m) ||
154-
setup_SubGlyph(m) ||
155-
setup_SubGlyphs(m) ||
156-
setup_TrueType(m) ||
157-
setup_TT_Header(m) ||
158-
setup_TT_HoriHeader(m) ||
159-
setup_TT_OS2(m) ||
160-
setup_TT_Pclt(m) ||
161-
setup_TT_Postscript(m) ||
162-
setup_TT_VertHeader(m) ||
163-
setup_Vector(m)
141+
setup_BBox(freetypy_module) ||
142+
setup_Bitmap(freetypy_module) ||
143+
setup_Bitmap_Size(freetypy_module) ||
144+
setup_CharIter(freetypy_module) ||
145+
setup_CharMap(freetypy_module) ||
146+
setup_Face(freetypy_module) ||
147+
setup_Glyph(freetypy_module) ||
148+
setup_Glyph_Metrics(freetypy_module) ||
149+
setup_Layout(freetypy_module) ||
150+
setup_Matrix(freetypy_module) ||
151+
setup_Outline(freetypy_module) ||
152+
setup_SfntName(freetypy_module) ||
153+
setup_SfntNames(freetypy_module) ||
154+
setup_Size(freetypy_module) ||
155+
setup_Size_Metrics(freetypy_module) ||
156+
setup_SubGlyph(freetypy_module) ||
157+
setup_SubGlyphs(freetypy_module) ||
158+
setup_TrueType(freetypy_module) ||
159+
setup_TT_Header(freetypy_module) ||
160+
setup_TT_HoriHeader(freetypy_module) ||
161+
setup_TT_OS2(freetypy_module) ||
162+
setup_TT_Pclt(freetypy_module) ||
163+
setup_TT_Postscript(freetypy_module) ||
164+
setup_TT_VertHeader(freetypy_module) ||
165+
setup_Vector(freetypy_module)
164166
)
165167
INITERROR;
166168

167169
#if PY3K
168-
return m;
170+
return freetypy_module;
169171
#endif
170172
}

src/freetypy.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ either expressed or implied, of the FreeBSD Project.
5050
FT_Library get_ft_library(void);
5151

5252

53+
extern PyObject *freetypy_module;
54+
55+
5356
#include "freetypy_error.h"
5457
#include "pyutil.h"
5558

src/glyph.c

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,11 @@ static PyTypeObject Py_Glyph_Type;
6060
static void
6161
Py_Glyph_dealloc(Py_Glyph* self)
6262
{
63-
Py_TYPE(self)->tp_clear((PyObject *)self);
6463
free(self->x);
65-
FT_Done_Glyph(self->glyph);
64+
if (self->glyph) {
65+
FT_Done_Glyph(self->glyph);
66+
}
67+
Py_TYPE(self)->tp_clear((PyObject*)self);
6668
Py_TYPE(self)->tp_free((PyObject*)self);
6769
}
6870

@@ -83,16 +85,26 @@ Py_Glyph_cnew(FT_GlyphSlot glyph_slot, PyObject *owner, int load_flags)
8385
return NULL;
8486
}
8587

88+
self->x = NULL;
89+
self->glyph = NULL;
90+
8691
glyph_slot_copy = PyMem_Malloc(sizeof(FT_GlyphSlotRec));
8792
if (glyph_slot_copy == NULL) {
8893
Py_DECREF(self);
8994
return NULL;
9095
}
9196
memcpy(glyph_slot_copy, glyph_slot, sizeof(FT_GlyphSlotRec));
9297
self->x = glyph_slot_copy;
93-
self->glyph = glyph;
98+
99+
if (ftpy_exc(FT_Glyph_Copy(glyph, &self->glyph))) {
100+
Py_DECREF(self);
101+
return NULL;
102+
}
103+
FT_Done_Glyph(glyph);
104+
94105
Py_INCREF(owner);
95106
self->base.owner = owner;
107+
96108
return (PyObject *)self;
97109
}
98110

@@ -107,6 +119,7 @@ Py_Glyph_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
107119
return NULL;
108120
}
109121
self->x = NULL;
122+
self->glyph = NULL;
110123
return (PyObject *)self;
111124
}
112125

src/outline.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,7 @@ Py_Outline_to_string_cubicto_func(
353353
typedef struct {
354354
ftpy_Object base;
355355
FT_Outline x;
356+
int inited;
356357
} Py_Outline;
357358

358359

@@ -370,7 +371,10 @@ static PyObject *Py_Outline_Contours_Buffer_cnew(PyObject *owner);
370371
static void
371372
Py_Outline_dealloc(Py_Outline* self)
372373
{
373-
FT_Outline_Done(get_ft_library(), &self->x);
374+
if (self->inited) {
375+
FT_Outline_Done(get_ft_library(), &self->x);
376+
}
377+
Py_TYPE(self)->tp_clear((PyObject*)self);
374378
Py_TYPE(self)->tp_free((PyObject*)self);
375379
}
376380

@@ -385,6 +389,8 @@ Py_Outline_cnew(FT_Outline *outline)
385389
return NULL;
386390
}
387391

392+
self->inited = 0;
393+
388394
if (ftpy_exc(
389395
FT_Outline_New(get_ft_library(),
390396
outline->n_points,
@@ -394,9 +400,10 @@ Py_Outline_cnew(FT_Outline *outline)
394400
return NULL;
395401
}
396402

403+
self->inited = 1;
404+
397405
if (ftpy_exc(
398406
FT_Outline_Copy(outline, &self->x))) {
399-
FT_Outline_Done(get_ft_library(), &self->x);
400407
Py_DECREF(self);
401408
return NULL;
402409
}
@@ -411,6 +418,7 @@ Py_Outline_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
411418
{
412419
Py_Outline *self;
413420
self = (Py_Outline *)type->tp_alloc(type, 0);
421+
self->inited = 0;
414422
return (PyObject *)self;
415423
}
416424

src/pyutil.c

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,7 @@ static const char *qualified_name_to_name(const char *qualified_name)
5454
static int
5555
generic_traverse(ftpy_Object *self, visitproc visit, void *arg)
5656
{
57-
int vret;
58-
59-
if (self->owner) {
60-
vret = visit(self->owner, arg);
61-
if (vret != 0)
62-
return vret;
63-
}
57+
Py_VISIT(self->owner);
6458

6559
return 0;
6660
}
@@ -81,7 +75,7 @@ generic_clear(ftpy_Object *self)
8175

8276
void ftpy_Object_dealloc(PyObject* self)
8377
{
84-
generic_clear((ftpy_Object *)self);
78+
Py_TYPE(self)->tp_clear((PyObject*)self);
8579
Py_TYPE(self)->tp_free((PyObject*)self);
8680
}
8781

0 commit comments

Comments
 (0)