mirror of
https://github.com/python/cpython.git
synced 2025-08-01 23:53:15 +00:00
bpo-31758: Prevent crashes when using an uninitialized _elementtree.XMLParser object (GH-3997)
This commit is contained in:
parent
63e5b59c06
commit
402e1cdb13
3 changed files with 41 additions and 0 deletions
|
@ -115,6 +115,21 @@ class MiscTests(unittest.TestCase):
|
||||||
elem.tail = X()
|
elem.tail = X()
|
||||||
elem.__setstate__({'tag': 42}) # shouldn't cause an assertion failure
|
elem.__setstate__({'tag': 42}) # shouldn't cause an assertion failure
|
||||||
|
|
||||||
|
@support.cpython_only
|
||||||
|
def test_uninitialized_parser(self):
|
||||||
|
# The interpreter shouldn't crash in case of calling methods or
|
||||||
|
# accessing attributes of uninitialized XMLParser objects.
|
||||||
|
parser = cET.XMLParser.__new__(cET.XMLParser)
|
||||||
|
self.assertRaises(ValueError, parser.close)
|
||||||
|
self.assertRaises(ValueError, parser.feed, 'foo')
|
||||||
|
class MockFile:
|
||||||
|
def read(*args):
|
||||||
|
return ''
|
||||||
|
self.assertRaises(ValueError, parser._parse_whole, MockFile())
|
||||||
|
self.assertRaises(ValueError, parser._setevents, None)
|
||||||
|
self.assertIsNone(parser.entity)
|
||||||
|
self.assertIsNone(parser.target)
|
||||||
|
|
||||||
def test_setstate_leaks(self):
|
def test_setstate_leaks(self):
|
||||||
# Test reference leaks
|
# Test reference leaks
|
||||||
elem = cET.Element.__new__(cET.Element)
|
elem = cET.Element.__new__(cET.Element)
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Prevent crashes when using an uninitialized ``_elementtree.XMLParser``
|
||||||
|
object. Patch by Oren Milman.
|
|
@ -3818,6 +3818,17 @@ xmlparser_dealloc(XMLParserObject* self)
|
||||||
Py_TYPE(self)->tp_free((PyObject *)self);
|
Py_TYPE(self)->tp_free((PyObject *)self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Py_LOCAL_INLINE(int)
|
||||||
|
_check_xmlparser(XMLParserObject* self)
|
||||||
|
{
|
||||||
|
if (self->target == NULL) {
|
||||||
|
PyErr_SetString(PyExc_ValueError,
|
||||||
|
"XMLParser.__init__() wasn't called");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
LOCAL(PyObject*)
|
LOCAL(PyObject*)
|
||||||
expat_parse(XMLParserObject* self, const char* data, int data_len, int final)
|
expat_parse(XMLParserObject* self, const char* data, int data_len, int final)
|
||||||
{
|
{
|
||||||
|
@ -3854,6 +3865,10 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self)
|
||||||
/* end feeding data to parser */
|
/* end feeding data to parser */
|
||||||
|
|
||||||
PyObject* res;
|
PyObject* res;
|
||||||
|
|
||||||
|
if (!_check_xmlparser(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
res = expat_parse(self, "", 0, 1);
|
res = expat_parse(self, "", 0, 1);
|
||||||
if (!res)
|
if (!res)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -3885,6 +3900,9 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
|
||||||
{
|
{
|
||||||
/* feed data to parser */
|
/* feed data to parser */
|
||||||
|
|
||||||
|
if (!_check_xmlparser(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (PyUnicode_Check(data)) {
|
if (PyUnicode_Check(data)) {
|
||||||
Py_ssize_t data_len;
|
Py_ssize_t data_len;
|
||||||
const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
|
const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
|
||||||
|
@ -3932,6 +3950,9 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
|
||||||
PyObject* temp;
|
PyObject* temp;
|
||||||
PyObject* res;
|
PyObject* res;
|
||||||
|
|
||||||
|
if (!_check_xmlparser(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
reader = PyObject_GetAttrString(file, "read");
|
reader = PyObject_GetAttrString(file, "read");
|
||||||
if (!reader)
|
if (!reader)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -4019,6 +4040,9 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
|
||||||
TreeBuilderObject *target;
|
TreeBuilderObject *target;
|
||||||
PyObject *events_append, *events_seq;
|
PyObject *events_append, *events_seq;
|
||||||
|
|
||||||
|
if (!_check_xmlparser(self)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (!TreeBuilder_CheckExact(self->target)) {
|
if (!TreeBuilder_CheckExact(self->target)) {
|
||||||
PyErr_SetString(
|
PyErr_SetString(
|
||||||
PyExc_TypeError,
|
PyExc_TypeError,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue