diff options
author | shadchin <[email protected]> | 2025-06-13 00:05:26 +0300 |
---|---|---|
committer | shadchin <[email protected]> | 2025-06-13 00:35:30 +0300 |
commit | 796b9088366b10b4cd42885101fc20c0b5709b07 (patch) | |
tree | f287eacb0b95ffd7cabf95b16cafb4788645dc38 /contrib/tools/python3/Modules/_elementtree.c | |
parent | c72bca862651e507d2ff4980ef7f4ff7267a7227 (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.c | 122 |
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; |