Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c194884

Browse files
committed
Sanitize and modernize some of the _elementtree code (see issue #16089).
1 parent 4524b46 commit c194884

1 file changed

Lines changed: 59 additions & 107 deletions

File tree

Modules/_elementtree.c

Lines changed: 59 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -123,66 +123,28 @@ deepcopy(PyObject* object, PyObject* memo)
123123
return NULL;
124124
}
125125

126-
args = PyTuple_New(2);
126+
args = PyTuple_Pack(2, object, memo);
127127
if (!args)
128128
return NULL;
129-
130-
Py_INCREF(object); PyTuple_SET_ITEM(args, 0, (PyObject*) object);
131-
Py_INCREF(memo); PyTuple_SET_ITEM(args, 1, (PyObject*) memo);
132-
133129
result = PyObject_CallObject(elementtree_deepcopy_obj, args);
134-
135130
Py_DECREF(args);
136-
137131
return result;
138132
}
139133

140134
LOCAL(PyObject*)
141135
list_join(PyObject* list)
142136
{
143137
/* join list elements (destroying the list in the process) */
144-
145138
PyObject* joiner;
146-
PyObject* function;
147-
PyObject* args;
148139
PyObject* result;
149140

150-
switch (PyList_GET_SIZE(list)) {
151-
case 0:
152-
Py_DECREF(list);
153-
return PyBytes_FromString("");
154-
case 1:
155-
result = PyList_GET_ITEM(list, 0);
156-
Py_INCREF(result);
157-
Py_DECREF(list);
158-
return result;
159-
}
160-
161-
/* two or more elements: slice out a suitable separator from the
162-
first member, and use that to join the entire list */
163-
164-
joiner = PySequence_GetSlice(PyList_GET_ITEM(list, 0), 0, 0);
141+
joiner = PyUnicode_FromStringAndSize("", 0);
165142
if (!joiner)
166143
return NULL;
167-
168-
function = PyObject_GetAttrString(joiner, "join");
169-
if (!function) {
170-
Py_DECREF(joiner);
171-
return NULL;
172-
}
173-
174-
args = PyTuple_New(1);
175-
if (!args)
176-
return NULL;
177-
178-
PyTuple_SET_ITEM(args, 0, list);
179-
180-
result = PyObject_CallObject(function, args);
181-
182-
Py_DECREF(args); /* also removes list */
183-
Py_DECREF(function);
144+
result = PyUnicode_Join(joiner, list);
184145
Py_DECREF(joiner);
185-
146+
if (result)
147+
Py_DECREF(list);
186148
return result;
187149
}
188150

@@ -399,6 +361,7 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
399361
return -1;
400362
if (kwds) {
401363
if (PyDict_Update(attrib, kwds) < 0) {
364+
Py_DECREF(attrib);
402365
return -1;
403366
}
404367
}
@@ -407,38 +370,34 @@ element_init(PyObject *self, PyObject *args, PyObject *kwds)
407370
attrib = get_attrib_from_keywords(kwds);
408371
if (!attrib)
409372
return -1;
410-
} else {
411-
/* no attrib arg, no kwds, so no attributes */
412-
Py_INCREF(Py_None);
413-
attrib = Py_None;
414373
}
415374

416375
self_elem = (ElementObject *)self;
417376

418-
if (attrib != Py_None && !is_empty_dict(attrib)) {
377+
if (attrib != NULL && !is_empty_dict(attrib)) {
419378
if (create_extra(self_elem, attrib) < 0) {
420-
PyObject_Del(self_elem);
379+
Py_DECREF(attrib);
421380
return -1;
422381
}
423382
}
424383

425384
/* We own a reference to attrib here and it's no longer needed. */
426-
Py_DECREF(attrib);
385+
Py_XDECREF(attrib);
427386

428387
/* Replace the objects already pointed to by tag, text and tail. */
429388
tmp = self_elem->tag;
430-
self_elem->tag = tag;
431389
Py_INCREF(tag);
390+
self_elem->tag = tag;
432391
Py_DECREF(tmp);
433392

434393
tmp = self_elem->text;
435-
self_elem->text = Py_None;
436394
Py_INCREF(Py_None);
395+
self_elem->text = Py_None;
437396
Py_DECREF(JOIN_OBJ(tmp));
438397

439398
tmp = self_elem->tail;
440-
self_elem->tail = Py_None;
441399
Py_INCREF(Py_None);
400+
self_elem->tail = Py_None;
442401
Py_DECREF(JOIN_OBJ(tmp));
443402

444403
return 0;
@@ -520,11 +479,11 @@ element_get_attrib(ElementObject* self)
520479
PyObject* res = self->extra->attrib;
521480

522481
if (res == Py_None) {
523-
Py_DECREF(res);
524482
/* create missing dictionary */
525483
res = PyDict_New();
526484
if (!res)
527485
return NULL;
486+
Py_DECREF(Py_None);
528487
self->extra->attrib = res;
529488
}
530489

@@ -824,7 +783,7 @@ element_deepcopy(ElementObject* self, PyObject* args)
824783
}
825784

826785
/* add object to memo dictionary (so deepcopy won't visit it again) */
827-
id = PyLong_FromLong((Py_uintptr_t) self);
786+
id = PyLong_FromSsize_t((Py_uintptr_t) self);
828787
if (!id)
829788
goto error;
830789

@@ -2081,6 +2040,7 @@ treebuilder_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
20812040
if (!t->stack) {
20822041
Py_DECREF(t->this);
20832042
Py_DECREF(t->last);
2043+
Py_DECREF((PyObject *) t);
20842044
return NULL;
20852045
}
20862046
t->index = 0;
@@ -2098,6 +2058,7 @@ treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds)
20982058
static char *kwlist[] = {"element_factory", 0};
20992059
PyObject *element_factory = NULL;
21002060
TreeBuilderObject *self_tb = (TreeBuilderObject *)self;
2061+
PyObject *tmp;
21012062

21022063
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:TreeBuilder", kwlist,
21032064
&element_factory)) {
@@ -2106,8 +2067,9 @@ treebuilder_init(PyObject *self, PyObject *args, PyObject *kwds)
21062067

21072068
if (element_factory) {
21082069
Py_INCREF(element_factory);
2109-
Py_XDECREF(self_tb->element_factory);
2070+
tmp = self_tb->element_factory;
21102071
self_tb->element_factory = element_factory;
2072+
Py_XDECREF(tmp);
21112073
}
21122074

21132075
return 0;
@@ -2128,17 +2090,17 @@ treebuilder_gc_traverse(TreeBuilderObject *self, visitproc visit, void *arg)
21282090
static int
21292091
treebuilder_gc_clear(TreeBuilderObject *self)
21302092
{
2131-
Py_XDECREF(self->end_ns_event_obj);
2132-
Py_XDECREF(self->start_ns_event_obj);
2133-
Py_XDECREF(self->end_event_obj);
2134-
Py_XDECREF(self->start_event_obj);
2135-
Py_XDECREF(self->events);
2136-
Py_DECREF(self->stack);
2137-
Py_XDECREF(self->data);
2138-
Py_DECREF(self->last);
2139-
Py_DECREF(self->this);
2093+
Py_CLEAR(self->end_ns_event_obj);
2094+
Py_CLEAR(self->start_ns_event_obj);
2095+
Py_CLEAR(self->end_event_obj);
2096+
Py_CLEAR(self->start_event_obj);
2097+
Py_CLEAR(self->events);
2098+
Py_CLEAR(self->stack);
2099+
Py_CLEAR(self->data);
2100+
Py_CLEAR(self->last);
2101+
Py_CLEAR(self->this);
21402102
Py_CLEAR(self->element_factory);
2141-
Py_XDECREF(self->root);
2103+
Py_CLEAR(self->root);
21422104
return 0;
21432105
}
21442106

@@ -2222,10 +2184,8 @@ treebuilder_handle_start(TreeBuilderObject* self, PyObject* tag,
22222184
if (self->start_event_obj) {
22232185
PyObject* res;
22242186
PyObject* action = self->start_event_obj;
2225-
res = PyTuple_New(2);
2187+
res = PyTuple_Pack(2, action, node);
22262188
if (res) {
2227-
Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
2228-
Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
22292189
PyList_Append(self->events, res);
22302190
Py_DECREF(res);
22312191
} else
@@ -2253,6 +2213,7 @@ treebuilder_handle_data(TreeBuilderObject* self, PyObject* data)
22532213
/* more than one item; use a list to collect items */
22542214
if (PyBytes_CheckExact(self->data) && Py_REFCNT(self->data) == 1 &&
22552215
PyBytes_CheckExact(data) && PyBytes_GET_SIZE(data) == 1) {
2216+
/* XXX this code path unused in Python 3? */
22562217
/* expat often generates single character data sections; handle
22572218
the most common case by resizing the existing string... */
22582219
Py_ssize_t size = PyBytes_GET_SIZE(self->data);
@@ -2317,10 +2278,8 @@ treebuilder_handle_end(TreeBuilderObject* self, PyObject* tag)
23172278
PyObject* res;
23182279
PyObject* action = self->end_event_obj;
23192280
PyObject* node = (PyObject*) self->last;
2320-
res = PyTuple_New(2);
2281+
res = PyTuple_Pack(2, action, node);
23212282
if (res) {
2322-
Py_INCREF(action); PyTuple_SET_ITEM(res, 0, (PyObject*) action);
2323-
Py_INCREF(node); PyTuple_SET_ITEM(res, 1, (PyObject*) node);
23242283
PyList_Append(self->events, res);
23252284
Py_DECREF(res);
23262285
} else
@@ -2366,8 +2325,12 @@ treebuilder_handle_namespace(TreeBuilderObject* self, int start,
23662325
PyTuple_SET_ITEM(res, 1, parcel);
23672326
PyList_Append(self->events, res);
23682327
Py_DECREF(res);
2369-
} else
2328+
}
2329+
else {
2330+
Py_DECREF(action);
2331+
Py_DECREF(parcel);
23702332
PyErr_Clear(); /* FIXME: propagate error */
2333+
}
23712334
}
23722335

23732336
/* -------------------------------------------------------------------- */
@@ -2526,7 +2489,7 @@ makeuniversal(XMLParserObject* self, const char* string)
25262489
/* convert a UTF-8 tag/attribute name from the expat parser
25272490
to a universal name string */
25282491

2529-
int size = strlen(string);
2492+
Py_ssize_t size = (Py_ssize_t) strlen(string);
25302493
PyObject* key;
25312494
PyObject* value;
25322495

@@ -2545,7 +2508,7 @@ makeuniversal(XMLParserObject* self, const char* string)
25452508

25462509
PyObject* tag;
25472510
char* p;
2548-
int i;
2511+
Py_ssize_t i;
25492512

25502513
/* look for namespace separator */
25512514
for (i = 0; i < size; i++)
@@ -2717,13 +2680,7 @@ expat_start_handler(XMLParserObject* self, const XML_Char* tag_in,
27172680
attrib_in += 2;
27182681
}
27192682
} else {
2720-
Py_INCREF(Py_None);
2721-
attrib = Py_None;
2722-
}
2723-
2724-
/* If we get None, pass an empty dictionary on */
2725-
if (attrib == Py_None) {
2726-
Py_DECREF(attrib);
2683+
/* Pass an empty dictionary on */
27272684
attrib = PyDict_New();
27282685
if (!attrib)
27292686
return;
@@ -3015,14 +2972,14 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds)
30152972

30162973
self_xp->names = PyDict_New();
30172974
if (!self_xp->names) {
3018-
Py_XDECREF(self_xp->entity);
2975+
Py_CLEAR(self_xp->entity);
30192976
return -1;
30202977
}
30212978

30222979
self_xp->parser = EXPAT(ParserCreate_MM)(encoding, &ExpatMemoryHandler, "}");
30232980
if (!self_xp->parser) {
3024-
Py_XDECREF(self_xp->entity);
3025-
Py_XDECREF(self_xp->names);
2981+
Py_CLEAR(self_xp->entity);
2982+
Py_CLEAR(self_xp->names);
30262983
PyErr_NoMemory();
30272984
return -1;
30282985
}
@@ -3032,8 +2989,8 @@ xmlparser_init(PyObject *self, PyObject *args, PyObject *kwds)
30322989
} else {
30332990
target = treebuilder_new(&TreeBuilder_Type, NULL, NULL);
30342991
if (!target) {
3035-
Py_XDECREF(self_xp->entity);
3036-
Py_XDECREF(self_xp->names);
2992+
Py_CLEAR(self_xp->entity);
2993+
Py_CLEAR(self_xp->names);
30372994
EXPAT(ParserFree)(self_xp->parser);
30382995
return -1;
30392996
}
@@ -3109,17 +3066,17 @@ xmlparser_gc_clear(XMLParserObject *self)
31093066
{
31103067
EXPAT(ParserFree)(self->parser);
31113068

3112-
Py_XDECREF(self->handle_close);
3113-
Py_XDECREF(self->handle_pi);
3114-
Py_XDECREF(self->handle_comment);
3115-
Py_XDECREF(self->handle_end);
3116-
Py_XDECREF(self->handle_data);
3117-
Py_XDECREF(self->handle_start);
3118-
Py_XDECREF(self->handle_doctype);
3069+
Py_CLEAR(self->handle_close);
3070+
Py_CLEAR(self->handle_pi);
3071+
Py_CLEAR(self->handle_comment);
3072+
Py_CLEAR(self->handle_end);
3073+
Py_CLEAR(self->handle_data);
3074+
Py_CLEAR(self->handle_start);
3075+
Py_CLEAR(self->handle_doctype);
31193076

3120-
Py_XDECREF(self->target);
3121-
Py_XDECREF(self->entity);
3122-
Py_XDECREF(self->names);
3077+
Py_CLEAR(self->target);
3078+
Py_CLEAR(self->entity);
3079+
Py_CLEAR(self->names);
31233080

31243081
return 0;
31253082
}
@@ -3227,17 +3184,12 @@ xmlparser_parse(XMLParserObject* self, PyObject* args)
32273184
break;
32283185
}
32293186
temp = PyUnicode_AsEncodedString(buffer, "utf-8", "surrogatepass");
3187+
Py_DECREF(buffer);
32303188
if (!temp) {
32313189
/* Propagate exception from PyUnicode_AsEncodedString */
3232-
Py_DECREF(buffer);
32333190
Py_DECREF(reader);
32343191
return NULL;
32353192
}
3236-
3237-
/* Here we no longer need the original buffer since it contains
3238-
* unicode. Make it point to the encoded bytes object.
3239-
*/
3240-
Py_DECREF(buffer);
32413193
buffer = temp;
32423194
}
32433195
else if (!PyBytes_CheckExact(buffer) || PyBytes_GET_SIZE(buffer) == 0) {
@@ -3307,10 +3259,10 @@ xmlparser_setevents(XMLParserObject *self, PyObject* args)
33073259
target->events = events;
33083260

33093261
/* clear out existing events */
3310-
Py_XDECREF(target->start_event_obj); target->start_event_obj = NULL;
3311-
Py_XDECREF(target->end_event_obj); target->end_event_obj = NULL;
3312-
Py_XDECREF(target->start_ns_event_obj); target->start_ns_event_obj = NULL;
3313-
Py_XDECREF(target->end_ns_event_obj); target->end_ns_event_obj = NULL;
3262+
Py_CLEAR(target->start_event_obj);
3263+
Py_CLEAR(target->end_event_obj);
3264+
Py_CLEAR(target->start_ns_event_obj);
3265+
Py_CLEAR(target->end_ns_event_obj);
33143266

33153267
if (event_set == Py_None) {
33163268
/* default is "end" only */

0 commit comments

Comments
 (0)