bpo-31758: Prevent crashes when using an uninitialized _elementtree.XMLParser object (GH-3997) (GH-19485)
(cherry picked from commit 402e1cdb13
)
This commit is contained in:
parent
ee249d798b
commit
61511488cf
|
@ -118,6 +118,21 @@ class MiscTests(unittest.TestCase):
|
|||
elem.tail = X()
|
||||
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):
|
||||
# Test reference leaks
|
||||
elem = cET.Element.__new__(cET.Element)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Prevent crashes when using an uninitialized ``_elementtree.XMLParser``
|
||||
object. Patch by Oren Milman.
|
|
@ -3877,6 +3877,17 @@ xmlparser_dealloc(XMLParserObject* 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*)
|
||||
expat_parse(XMLParserObject* self, const char* data, int data_len, int final)
|
||||
{
|
||||
|
@ -3913,6 +3924,10 @@ _elementtree_XMLParser_close_impl(XMLParserObject *self)
|
|||
/* end feeding data to parser */
|
||||
|
||||
PyObject* res;
|
||||
|
||||
if (!_check_xmlparser(self)) {
|
||||
return NULL;
|
||||
}
|
||||
res = expat_parse(self, "", 0, 1);
|
||||
if (!res)
|
||||
return NULL;
|
||||
|
@ -3944,6 +3959,9 @@ _elementtree_XMLParser_feed(XMLParserObject *self, PyObject *data)
|
|||
{
|
||||
/* feed data to parser */
|
||||
|
||||
if (!_check_xmlparser(self)) {
|
||||
return NULL;
|
||||
}
|
||||
if (PyUnicode_Check(data)) {
|
||||
Py_ssize_t data_len;
|
||||
const char *data_ptr = PyUnicode_AsUTF8AndSize(data, &data_len);
|
||||
|
@ -3991,6 +4009,9 @@ _elementtree_XMLParser__parse_whole(XMLParserObject *self, PyObject *file)
|
|||
PyObject* temp;
|
||||
PyObject* res;
|
||||
|
||||
if (!_check_xmlparser(self)) {
|
||||
return NULL;
|
||||
}
|
||||
reader = PyObject_GetAttrString(file, "read");
|
||||
if (!reader)
|
||||
return NULL;
|
||||
|
@ -4078,6 +4099,9 @@ _elementtree_XMLParser__setevents_impl(XMLParserObject *self,
|
|||
TreeBuilderObject *target;
|
||||
PyObject *events_append, *events_seq;
|
||||
|
||||
if (!_check_xmlparser(self)) {
|
||||
return NULL;
|
||||
}
|
||||
if (!TreeBuilder_CheckExact(self->target)) {
|
||||
PyErr_SetString(
|
||||
PyExc_TypeError,
|
||||
|
|
Loading…
Reference in New Issue