Skip to content

Commit 931331a

Browse files
Issue #25019: Fixed a crash caused by setting non-string key of expat parser.
Added additional tests for expat parser attributes. Based on patch by John Leitch.
1 parent eba8fee commit 931331a

4 files changed

Lines changed: 51 additions & 16 deletions

File tree

Lib/test/test_pyexpat.py

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,47 @@
1616
class SetAttributeTest(unittest.TestCase):
1717
def setUp(self):
1818
self.parser = expat.ParserCreate(namespace_separator='!')
19-
self.set_get_pairs = [
20-
[0, 0],
21-
[1, 1],
22-
[2, 1],
23-
[0, 0],
24-
]
19+
20+
def test_buffer_text(self):
21+
self.assertIs(self.parser.buffer_text, False)
22+
for x in 0, 1, 2, 0:
23+
self.parser.buffer_text = x
24+
self.assertIs(self.parser.buffer_text, bool(x))
25+
26+
def test_namespace_prefixes(self):
27+
self.assertIs(self.parser.namespace_prefixes, False)
28+
for x in 0, 1, 2, 0:
29+
self.parser.namespace_prefixes = x
30+
self.assertIs(self.parser.namespace_prefixes, bool(x))
2531

2632
def test_ordered_attributes(self):
27-
for x, y in self.set_get_pairs:
33+
self.assertIs(self.parser.ordered_attributes, False)
34+
for x in 0, 1, 2, 0:
2835
self.parser.ordered_attributes = x
29-
self.assertEqual(self.parser.ordered_attributes, y)
36+
self.assertIs(self.parser.ordered_attributes, bool(x))
37+
38+
def test_specified_attributes(self):
39+
self.assertIs(self.parser.specified_attributes, False)
40+
for x in 0, 1, 2, 0:
41+
self.parser.specified_attributes = x
42+
self.assertIs(self.parser.specified_attributes, bool(x))
3043

3144
def test_specified_attributes(self):
32-
for x, y in self.set_get_pairs:
45+
self.assertIs(self.parser.specified_attributes, False)
46+
for x in 0, 1, 2, 0:
3347
self.parser.specified_attributes = x
34-
self.assertEqual(self.parser.specified_attributes, y)
48+
self.assertIs(self.parser.specified_attributes, bool(x))
49+
50+
def test_invalid_attributes(self):
51+
with self.assertRaises(AttributeError):
52+
self.parser.returns_unicode = 1
53+
with self.assertRaises(AttributeError):
54+
self.parser.returns_unicode
55+
56+
# Issue #25019
57+
self.assertRaises(TypeError, setattr, self.parser, range(0xF), 0)
58+
self.assertRaises(TypeError, self.parser.__setattr__, range(0xF), 0)
59+
self.assertRaises(TypeError, getattr, self.parser, range(0xF))
3560

3661

3762
data = b'''\
@@ -514,11 +539,12 @@ def test_1000_bytes(self):
514539
def test_wrong_size(self):
515540
parser = expat.ParserCreate()
516541
parser.buffer_text = 1
517-
def f(size):
518-
parser.buffer_size = size
519-
520-
self.assertRaises(ValueError, f, -1)
521-
self.assertRaises(ValueError, f, 0)
542+
with self.assertRaises(ValueError):
543+
parser.buffer_size = -1
544+
with self.assertRaises(ValueError):
545+
parser.buffer_size = 0
546+
with self.assertRaises(TypeError):
547+
parser.buffer_size = 512.0
522548

523549
def test_unchanged_size(self):
524550
xml1 = b"<?xml version='1.0' encoding='iso8859'?><s>" + b'a' * 512

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,7 @@ Joerg Lehmann
807807
Robert Lehmann
808808
Petri Lehtinen
809809
Luke Kenneth Casson Leighton
810+
John Leitch
810811
Tshepang Lekhonkhobe
811812
Marc-André Lemburg
812813
Mateusz Lenik

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ Core and Builtins
8181
Library
8282
-------
8383

84+
- Issue #25019: Fixed a crash caused by setting non-string key of expat parser.
85+
Based on patch by John Leitch.
86+
8487
- Issue #24917: time_strftime() buffer over-read.
8588

8689
- Issue #23144: Make sure that HTMLParser.feed() returns all the data, even

Modules/pyexpat.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1341,11 +1341,16 @@ static int
13411341
xmlparse_setattro(xmlparseobject *self, PyObject *name, PyObject *v)
13421342
{
13431343
/* Set attribute 'name' to value 'v'. v==NULL means delete */
1344+
if (!PyUnicode_Check(name)) {
1345+
PyErr_Format(PyExc_TypeError,
1346+
"attribute name must be string, not '%.200s'",
1347+
name->ob_type->tp_name);
1348+
return -1;
1349+
}
13441350
if (v == NULL) {
13451351
PyErr_SetString(PyExc_RuntimeError, "Cannot delete attribute");
13461352
return -1;
13471353
}
1348-
assert(PyUnicode_Check(name));
13491354
if (PyUnicode_CompareWithASCIIString(name, "buffer_text") == 0) {
13501355
int b = PyObject_IsTrue(v);
13511356
if (b < 0)

0 commit comments

Comments
 (0)