summaryrefslogtreecommitdiffstats
path: root/contrib/tools/python3/Modules/_elementtree.c
diff options
context:
space:
mode:
authorshadchin <[email protected]>2025-06-13 00:05:26 +0300
committershadchin <[email protected]>2025-06-13 00:35:30 +0300
commit796b9088366b10b4cd42885101fc20c0b5709b07 (patch)
treef287eacb0b95ffd7cabf95b16cafb4788645dc38 /contrib/tools/python3/Modules/_elementtree.c
parentc72bca862651e507d2ff4980ef7f4ff7267a7227 (diff)
Update Python 3 to 3.12.10
commit_hash:dd2398e159fe1d72ea6b12da52fccc933a41a785
Diffstat (limited to 'contrib/tools/python3/Modules/_elementtree.c')
-rw-r--r--contrib/tools/python3/Modules/_elementtree.c122
1 files changed, 60 insertions, 62 deletions
diff --git a/contrib/tools/python3/Modules/_elementtree.c b/contrib/tools/python3/Modules/_elementtree.c
index 386f38add16..56d1508af13 100644
--- a/contrib/tools/python3/Modules/_elementtree.c
+++ b/contrib/tools/python3/Modules/_elementtree.c
@@ -845,6 +845,7 @@ _elementtree_Element___deepcopy___impl(ElementObject *self, PyObject *memo)
if (element_resize(element, self->extra->length) < 0)
goto error;
+ // TODO(picnixz): check for an evil child's __deepcopy__ on 'self'
for (i = 0; i < self->extra->length; i++) {
PyObject* child = deepcopy(st, self->extra->children[i], memo);
if (!child || !Element_Check(st, child)) {
@@ -1249,29 +1250,28 @@ _elementtree_Element_find_impl(ElementObject *self, PyTypeObject *cls,
PyObject *path, PyObject *namespaces)
/*[clinic end generated code: output=18f77d393c9fef1b input=94df8a83f956acc6]*/
{
- Py_ssize_t i;
elementtreestate *st = get_elementtree_state_by_cls(cls);
if (checkpath(path) || namespaces != Py_None) {
return PyObject_CallMethodObjArgs(
st->elementpath_obj, st->str_find, self, path, namespaces, NULL
- );
+ );
}
- if (!self->extra)
- Py_RETURN_NONE;
-
- for (i = 0; i < self->extra->length; i++) {
- PyObject* item = self->extra->children[i];
- int rc;
+ for (Py_ssize_t i = 0; self->extra && i < self->extra->length; i++) {
+ PyObject *item = self->extra->children[i];
assert(Element_Check(st, item));
Py_INCREF(item);
- rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
- if (rc > 0)
+ PyObject *tag = Py_NewRef(((ElementObject *)item)->tag);
+ int rc = PyObject_RichCompareBool(tag, path, Py_EQ);
+ Py_DECREF(tag);
+ if (rc > 0) {
return item;
+ }
Py_DECREF(item);
- if (rc < 0)
+ if (rc < 0) {
return NULL;
+ }
}
Py_RETURN_NONE;
@@ -1294,38 +1294,34 @@ _elementtree_Element_findtext_impl(ElementObject *self, PyTypeObject *cls,
PyObject *namespaces)
/*[clinic end generated code: output=6af7a2d96aac32cb input=32f252099f62a3d2]*/
{
- Py_ssize_t i;
elementtreestate *st = get_elementtree_state_by_cls(cls);
if (checkpath(path) || namespaces != Py_None)
return PyObject_CallMethodObjArgs(
st->elementpath_obj, st->str_findtext,
self, path, default_value, namespaces, NULL
- );
-
- if (!self->extra) {
- return Py_NewRef(default_value);
- }
+ );
- for (i = 0; i < self->extra->length; i++) {
+ for (Py_ssize_t i = 0; self->extra && i < self->extra->length; i++) {
PyObject *item = self->extra->children[i];
- int rc;
assert(Element_Check(st, item));
Py_INCREF(item);
- rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
+ PyObject *tag = Py_NewRef(((ElementObject *)item)->tag);
+ int rc = PyObject_RichCompareBool(tag, path, Py_EQ);
+ Py_DECREF(tag);
if (rc > 0) {
- PyObject* text = element_get_text((ElementObject*)item);
+ PyObject *text = element_get_text((ElementObject *)item);
+ Py_DECREF(item);
if (text == Py_None) {
- Py_DECREF(item);
return PyUnicode_New(0, 0);
}
Py_XINCREF(text);
- Py_DECREF(item);
return text;
}
Py_DECREF(item);
- if (rc < 0)
+ if (rc < 0) {
return NULL;
+ }
}
return Py_NewRef(default_value);
@@ -1346,29 +1342,26 @@ _elementtree_Element_findall_impl(ElementObject *self, PyTypeObject *cls,
PyObject *path, PyObject *namespaces)
/*[clinic end generated code: output=65e39a1208f3b59e input=7aa0db45673fc9a5]*/
{
- Py_ssize_t i;
- PyObject* out;
elementtreestate *st = get_elementtree_state_by_cls(cls);
if (checkpath(path) || namespaces != Py_None) {
return PyObject_CallMethodObjArgs(
st->elementpath_obj, st->str_findall, self, path, namespaces, NULL
- );
+ );
}
- out = PyList_New(0);
- if (!out)
+ PyObject *out = PyList_New(0);
+ if (out == NULL) {
return NULL;
+ }
- if (!self->extra)
- return out;
-
- for (i = 0; i < self->extra->length; i++) {
- PyObject* item = self->extra->children[i];
- int rc;
+ for (Py_ssize_t i = 0; self->extra && i < self->extra->length; i++) {
+ PyObject *item = self->extra->children[i];
assert(Element_Check(st, item));
Py_INCREF(item);
- rc = PyObject_RichCompareBool(((ElementObject*)item)->tag, path, Py_EQ);
+ PyObject *tag = Py_NewRef(((ElementObject *)item)->tag);
+ int rc = PyObject_RichCompareBool(tag, path, Py_EQ);
+ Py_DECREF(tag);
if (rc != 0 && (rc < 0 || PyList_Append(out, item) < 0)) {
Py_DECREF(item);
Py_DECREF(out);
@@ -1635,42 +1628,47 @@ _elementtree_Element_remove_impl(ElementObject *self, PyObject *subelement)
/*[clinic end generated code: output=38fe6c07d6d87d1f input=6133e1d05597d5ee]*/
{
Py_ssize_t i;
- int rc;
- PyObject *found;
-
- if (!self->extra) {
- /* element has no children, so raise exception */
- PyErr_SetString(
- PyExc_ValueError,
- "list.remove(x): x not in list"
- );
- return NULL;
- }
-
- for (i = 0; i < self->extra->length; i++) {
- if (self->extra->children[i] == subelement)
+ // When iterating over the list of children, we need to check that the
+ // list is not cleared (self->extra != NULL) and that we are still within
+ // the correct bounds (i < self->extra->length).
+ //
+ // We deliberately avoid protecting against children lists that grow
+ // faster than the index since list objects do not protect against it.
+ int rc = 0;
+ for (i = 0; self->extra && i < self->extra->length; i++) {
+ if (self->extra->children[i] == subelement) {
+ rc = 1;
break;
- rc = PyObject_RichCompareBool(self->extra->children[i], subelement, Py_EQ);
- if (rc > 0)
- break;
- if (rc < 0)
+ }
+ PyObject *child = Py_NewRef(self->extra->children[i]);
+ rc = PyObject_RichCompareBool(child, subelement, Py_EQ);
+ Py_DECREF(child);
+ if (rc < 0) {
return NULL;
+ }
+ else if (rc > 0) {
+ break;
+ }
}
- if (i >= self->extra->length) {
- /* subelement is not in children, so raise exception */
- PyErr_SetString(
- PyExc_ValueError,
- "list.remove(x): x not in list"
- );
+ if (rc == 0) {
+ PyErr_SetString(PyExc_ValueError, "list.remove(x): x not in list");
return NULL;
}
- found = self->extra->children[i];
+ // An extra check must be done if the mutation occurs at the very last
+ // step and removes or clears the 'extra' list (the condition on the
+ // length would not be satisfied any more).
+ if (self->extra == NULL || i >= self->extra->length) {
+ Py_RETURN_NONE;
+ }
+
+ PyObject *found = self->extra->children[i];
self->extra->length--;
- for (; i < self->extra->length; i++)
+ for (; i < self->extra->length; i++) {
self->extra->children[i] = self->extra->children[i+1];
+ }
Py_DECREF(found);
Py_RETURN_NONE;