python / python/cpython

xml.dom.minidom: DOMBuilderFilter accept/reject is inverted for notation declarations

Open
#152,142 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

3.13 3.14 3.15 3.16 stdlib topic-XML type-bug
Dominant language
Python
Stars
77.2k
Forks
35.9k
PR merge metrics
PR metrics pending

Description

ExpatBuilder.notation_decl_handler in Lib/xml/dom/expatbuilder.py drops a notation when the DOMBuilderFilter accepts it and keeps it when the filter rejects it, the opposite of every other filtered handler in that file and of the DOMBuilderFilter contract (FILTER_REJECT drops the node, FILTER_ACCEPT keeps it).

import io
import xml.dom.expatbuilder as eb
from xml.dom.xmlbuilder import DOMBuilderFilter, Options

src = b'<?xml version="1.0"?><!DOCTYPE root [<!NOTATION gif PUBLIC "image/gif">]><root/>'

class RejectNotations(DOMBuilderFilter):
    def acceptNode(self, node):
        if node.nodeType == node.NOTATION_NODE:
            return self.FILTER_REJECT
        return self.FILTER_ACCEPT
    def startContainer(self, node):
        return self.FILTER_ACCEPT

opts = Options()
opts.filter = RejectNotations()
doc = eb.makeBuilder(opts).parseFile(io.BytesIO(src))
print(doc.doctype.notations.length)   # 1 -- the filter rejected it but it was kept

The handler compares against FILTER_ACCEPT:

self.document.doctype.notations._seq.append(node)
if self._filter and self._filter.acceptNode(node) == FILTER_ACCEPT:
    del self.document.doctype.notations._seq[-1]

while the sibling entity_decl_handler (and the element, comment and processing-instruction handlers) compare against FILTER_REJECT. So an accepted notation is dropped and a rejected one is kept.

Reproduces on main and on released 3.x. Lib/test/test_minidom.py has no DOMBuilderFilter coverage for notations.

Linked PRs
  • gh-152143

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in Lib/xml/dom/expatbuilder.py at ExpatBuilder.notation_decl_handler and compare it with entity_decl_handler and the other filtered handlers. Add DOMBuilderFilter coverage for notation declarations in Lib/test/test_minidom.py, using the reproduction to verify that rejected notations are omitted and accepted ones remain.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.