|
11 | 11 | from xml.sax.saxutils import XMLGenerator, escape, unescape, quoteattr, \ |
12 | 12 | XMLFilterBase |
13 | 13 | from xml.sax.expatreader import create_parser |
| 14 | +from xml.sax.handler import feature_namespaces |
14 | 15 | from xml.sax.xmlreader import InputSource, AttributesImpl, AttributesNSImpl |
15 | 16 | from io import StringIO |
16 | 17 | from test.support import findfile, run_unittest |
@@ -385,6 +386,60 @@ def test_1463026_3_empty(self): |
385 | 386 | self.assertEquals(result.getvalue(), |
386 | 387 | start+'<my:a xmlns:my="qux" b="c"/>') |
387 | 388 |
|
| 389 | + def test_5027_1(self): |
| 390 | + # The xml prefix (as in xml:lang below) is reserved and bound by |
| 391 | + # definition to http://www.w3.org/XML/1998/namespace. XMLGenerator had |
| 392 | + # a bug whereby a KeyError is thrown because this namespace is missing |
| 393 | + # from a dictionary. |
| 394 | + # |
| 395 | + # This test demonstrates the bug by parsing a document. |
| 396 | + test_xml = StringIO( |
| 397 | + '<?xml version="1.0"?>' |
| 398 | + '<a:g1 xmlns:a="http://example.com/ns">' |
| 399 | + '<a:g2 xml:lang="en">Hello</a:g2>' |
| 400 | + '</a:g1>') |
| 401 | + |
| 402 | + parser = make_parser() |
| 403 | + parser.setFeature(feature_namespaces, True) |
| 404 | + result = StringIO() |
| 405 | + gen = XMLGenerator(result) |
| 406 | + parser.setContentHandler(gen) |
| 407 | + parser.parse(test_xml) |
| 408 | + |
| 409 | + self.assertEquals(result.getvalue(), |
| 410 | + start + ( |
| 411 | + '<a:g1 xmlns:a="http://example.com/ns">' |
| 412 | + '<a:g2 xml:lang="en">Hello</a:g2>' |
| 413 | + '</a:g1>')) |
| 414 | + |
| 415 | + def test_5027_2(self): |
| 416 | + # The xml prefix (as in xml:lang below) is reserved and bound by |
| 417 | + # definition to http://www.w3.org/XML/1998/namespace. XMLGenerator had |
| 418 | + # a bug whereby a KeyError is thrown because this namespace is missing |
| 419 | + # from a dictionary. |
| 420 | + # |
| 421 | + # This test demonstrates the bug by direct manipulation of the |
| 422 | + # XMLGenerator. |
| 423 | + result = StringIO() |
| 424 | + gen = XMLGenerator(result) |
| 425 | + |
| 426 | + gen.startDocument() |
| 427 | + gen.startPrefixMapping('a', 'http://example.com/ns') |
| 428 | + gen.startElementNS(('http://example.com/ns', 'g1'), 'g1', {}) |
| 429 | + lang_attr = {('http://www.w3.org/XML/1998/namespace', 'lang'): 'en'} |
| 430 | + gen.startElementNS(('http://example.com/ns', 'g2'), 'g2', lang_attr) |
| 431 | + gen.characters('Hello') |
| 432 | + gen.endElementNS(('http://example.com/ns', 'g2'), 'g2') |
| 433 | + gen.endElementNS(('http://example.com/ns', 'g1'), 'g1') |
| 434 | + gen.endPrefixMapping('a') |
| 435 | + gen.endDocument() |
| 436 | + |
| 437 | + self.assertEquals(result.getvalue(), |
| 438 | + start + ( |
| 439 | + '<a:g1 xmlns:a="http://example.com/ns">' |
| 440 | + '<a:g2 xml:lang="en">Hello</a:g2>' |
| 441 | + '</a:g1>')) |
| 442 | + |
388 | 443 |
|
389 | 444 | class XMLFilterBaseTest(unittest.TestCase): |
390 | 445 | def test_filter_basic(self): |
|
0 commit comments