-
-
Notifications
You must be signed in to change notification settings - Fork 33.7k
bpo-31728: Prevent crashes in _elementtree due to unsafe cleanup of Element.text and Element.tail #3924
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Modules/_elementtree.c
Outdated
|
|
||
| Py_INCREF(Py_None); | ||
| Py_DECREF(JOIN_OBJ(self->text)); | ||
| _clear_joined_ptr(&self->text); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Setting self->text to NULL is not safe. In this case the "text" getter will return NULL without setting an exception.
| elem = cET.Element('elem') | ||
| class X: | ||
| def __del__(self): | ||
| elem.clear() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Getting elem.text or elem.tail before calling elem.clear() will crash.
|
A Python core developer has requested some changes be made to your pull request before we can consider merging it. If you could please address their requests along with any other requests in other reviews from core developers that would be appreciated. Once you have made the requested changes, please leave a comment on this pull request containing the phrase |
|
In the end of I didn't expect the Spanish Inquisition! |
|
Nobody expects the Spanish Inquisition! @serhiy-storchaka: please review the changes made to this pull request. |
serhiy-storchaka
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be an improvement if use the new helper in element_init(), _elementtree_Element___copy___impl(), _elementtree_Element___deepcopy___impl().
It may be worth to move Py_INCREF() out of _set_joined_ptr(). This will help in _elementtree_Element___deepcopy___impl() and will allow to implement _clear_joined_ptr(p) as _set_joined_ptr(p, NULL).
Modules/_elementtree.c
Outdated
| } | ||
|
|
||
| /* Py_INCREF followed by Py_SETREF for a PyObject* that uses a join flag. */ | ||
| static void _set_joined_ptr(PyObject **p, PyObject *new_joined_ptr) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move static void on a separate line. Or better even use LOCAL(void) or Py_LOCAL_INLINE(void).
* implement _clear_joined_ptr() using _set_joined_ptr(). * use _set_joined_ptr() in more methods.
Modules/_elementtree.c
Outdated
| Py_DECREF(JOIN_OBJ(element->text)); | ||
| element->text = self->text; | ||
| _set_joined_ptr(&element->text, self->text); | ||
| Py_INCREF(JOIN_OBJ(element->text)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new reference should be incremented before decrementing the old reference.
In this particular case the order doesn't matter since the old reference is None, and decrementing it can't trigger executing a user code. But for unifying the code I would move the incrementation above _set_joined_ptr().
Modules/_elementtree.c
Outdated
| _clear_joined_ptr(&self->text); | ||
| self->text = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; | ||
| Py_INCREF(JOIN_OBJ(self->text)); | ||
| new_val = text ? JOIN_SET(text, PyList_CheckExact(text)) : Py_None; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can reuse the text variable for the new value. The old value no longer used.
|
And the last comment. The NEWS.d entry should be in the "Library" section. |
|
Thanks @orenmn for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6. |
|
@orenmn and @serhiy-storchaka, Something is wrong... I can't backport for now. |
|
Thank you @orenmn! Do you mind to make backports? |
|
@orenmn and @serhiy-storchaka, Something is wrong... I can't backport for now. |
|
Thanks @orenmn for the PR, and @serhiy-storchaka for merging it 🌮🎉.. I'm working now to backport this PR to: 2.7, 3.6. |
|
GH-3945 is a backport of this pull request to the 3.6 branch. |
…p of Element.text and Element.tail (pythonGH-3924) (cherry picked from commit 39ecb9c)
|
Sorry, @orenmn and @serhiy-storchaka, I could not cleanly backport this to |
|
(i am working on a backport to 2.7) |
|
GH-3950 is a backport of this pull request to the 2.7 branch. |
In addition, add tests to
test_xml_etree_cto verify that the crashes are no more.https://bugs.python.org/issue31728