Skip to content

Commit 1dca604

Browse files
committed
Add tp_clear slot and remove UB casts
1 parent a21391a commit 1dca604

File tree

3 files changed

+43
-12
lines changed

3 files changed

+43
-12
lines changed

Include/internal/pycore_template.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ extern PyTypeObject _PyTemplate_Type;
1313
extern PyTypeObject _PyTemplateIter_Type;
1414

1515
#define _PyTemplate_CheckExact(op) Py_IS_TYPE((op), &_PyTemplate_Type)
16+
#define _PyTemplateIter_CheckExact(op) Py_IS_TYPE((op), &_PyTemplateIter_Type)
1617

1718
extern PyObject *_PyTemplate_Concat(PyObject *self, PyObject *other);
1819

Objects/interpolationobject.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,14 +79,21 @@ interpolation_new_impl(PyTypeObject *type, PyObject *value,
7979

8080
static void
8181
interpolation_dealloc(PyObject *op)
82+
{
83+
PyObject_GC_UnTrack(op);
84+
Py_TYPE(op)->tp_clear(op);
85+
Py_TYPE(op)->tp_free(op);
86+
}
87+
88+
static int
89+
interpolation_clear(PyObject *op)
8290
{
8391
interpolationobject *self = interpolationobject_CAST(op);
84-
PyObject_GC_UnTrack(self);
8592
Py_CLEAR(self->value);
8693
Py_CLEAR(self->expression);
8794
Py_CLEAR(self->conversion);
8895
Py_CLEAR(self->format_spec);
89-
Py_TYPE(self)->tp_free(self);
96+
return 0;
9097
}
9198

9299
static int
@@ -127,6 +134,7 @@ PyTypeObject _PyInterpolation_Type = {
127134
.tp_new = interpolation_new,
128135
.tp_alloc = PyType_GenericAlloc,
129136
.tp_dealloc = interpolation_dealloc,
137+
.tp_clear = interpolation_clear,
130138
.tp_free = PyObject_GC_Del,
131139
.tp_repr = interpolation_repr,
132140
.tp_members = interpolation_members,

Objects/templateobject.c

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,13 @@ typedef struct {
1111
int from_strings;
1212
} templateiterobject;
1313

14+
#define templateiterobject_CAST(op) \
15+
(assert(_PyTemplateIter_CheckExact(op)), _Py_CAST(templateiterobject*, (op)))
16+
1417
static PyObject *
15-
templateiter_next(templateiterobject *self)
18+
templateiter_next(PyObject *op)
1619
{
20+
templateiterobject *self = templateiterobject_CAST(op);
1721
PyObject *item;
1822
if (self->from_strings) {
1923
item = PyIter_Next(self->stringsiter);
@@ -30,17 +34,26 @@ templateiter_next(templateiterobject *self)
3034
}
3135

3236
static void
33-
templateiter_dealloc(templateiterobject *self)
37+
templateiter_dealloc(PyObject *op)
38+
{
39+
PyObject_GC_UnTrack(op);
40+
Py_TYPE(op)->tp_clear(op);
41+
Py_TYPE(op)->tp_free(op);
42+
}
43+
44+
static int
45+
templateiter_clear(PyObject *op)
3446
{
35-
PyObject_GC_UnTrack(self);
47+
templateiterobject *self = templateiterobject_CAST(op);
3648
Py_CLEAR(self->stringsiter);
3749
Py_CLEAR(self->interpolationsiter);
38-
Py_TYPE(self)->tp_free(self);
50+
return 0;
3951
}
4052

4153
static int
42-
templateiter_traverse(templateiterobject *self, visitproc visit, void *arg)
54+
templateiter_traverse(PyObject *op, visitproc visit, void *arg)
4355
{
56+
templateiterobject *self = templateiterobject_CAST(op);
4457
Py_VISIT(self->stringsiter);
4558
Py_VISIT(self->interpolationsiter);
4659
return 0;
@@ -54,11 +67,12 @@ PyTypeObject _PyTemplateIter_Type = {
5467
.tp_itemsize = 0,
5568
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
5669
.tp_alloc = PyType_GenericAlloc,
57-
.tp_dealloc = (destructor) templateiter_dealloc,
70+
.tp_dealloc = templateiter_dealloc,
71+
.tp_clear = templateiter_clear,
5872
.tp_free = PyObject_GC_Del,
59-
.tp_traverse = (traverseproc) templateiter_traverse,
73+
.tp_traverse = templateiter_traverse,
6074
.tp_iter = PyObject_SelfIter,
61-
.tp_iternext = (iternextfunc) templateiter_next,
75+
.tp_iternext = templateiter_next,
6276
};
6377

6478
typedef struct {
@@ -159,12 +173,19 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
159173

160174
static void
161175
template_dealloc(PyObject *op)
176+
{
177+
PyObject_GC_UnTrack(op);
178+
Py_TYPE(op)->tp_clear(op);
179+
Py_TYPE(op)->tp_free(op);
180+
}
181+
182+
static int
183+
template_clear(PyObject *op)
162184
{
163185
templateobject *self = templateobject_CAST(op);
164-
PyObject_GC_UnTrack(self);
165186
Py_CLEAR(self->strings);
166187
Py_CLEAR(self->interpolations);
167-
Py_TYPE(self)->tp_free(self);
188+
return 0;
168189
}
169190

170191
static int
@@ -413,6 +434,7 @@ PyTypeObject _PyTemplate_Type = {
413434
.tp_new = template_new,
414435
.tp_alloc = PyType_GenericAlloc,
415436
.tp_dealloc = template_dealloc,
437+
.tp_clear = template_clear,
416438
.tp_free = PyObject_GC_Del,
417439
.tp_repr = template_repr,
418440
.tp_members = template_members,

0 commit comments

Comments
 (0)