GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-57092: Add the validate option to xml.sax.saxutils.XMLGenerator by serhiy-storchaka · Pull Request #156800 · python/cpython

Conversation

@serhiy-storchaka

@serhiy-storchaka serhiy-storchaka commented Sep 1, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

If validate is true, XMLGenerator checks that element and attribute names and namespace prefixes are valid, that all characters are legal, and that the content of processing instructions does not contain illegal sequences. ValueError is raised if any check fails.

It is disabled by default, because the events produced by a parser are always valid, and checking almost doubles the time of generating a document.

The option is the counterpart of the validate option added to xml.etree.ElementTree in #149469.

Based on #156799.

  • Issue: xml.sax.xmlreader.AttributesImpl allows empty string as attribute names #57092

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
serhiy-storchaka added 2 commits September 1, 2026 22:44
@serhiy-storchaka
pythongh-156797: Escape the namespace URI in xml.sax.saxutils.XMLGene…
fe4de69
…rator

The namespace declarations were the only attribute values written without
quoteattr(), so a URI containing "&", "<" or a quote character produced a
document which cannot be parsed.
@serhiy-storchaka
pythongh-57092: Add the validate option to xml.sax.saxutils.XMLGenerator
be69186
If it is true, invalid names, illegal characters and other content which
cannot be represented in a well-formed XML document are rejected with
ValueError.  It is disabled by default, because the events produced by a
parser are always valid, and the check would almost double the cost of
generating a document.
@serhiy-storchaka
serhiy-storchaka requested a review from AA-Turner as a code owner September 1, 2026 20:12
@bedevere-app bedevere-app Bot mentioned this pull request Sep 1, 2026
xml.sax.xmlreader.AttributesImpl allows empty string as attribute names #57092
Open
@bedevere-app bedevere-app Bot added the awaiting core review label Sep 1, 2026
@read-the-docs-community

read-the-docs-community Bot commented Sep 1, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

Documentation build overview

📚 cpython-previews | 🛠️ Build #35822273 | 📁 Comparing 347e135 against main (42de93a)

  🔍 Preview build  

294 files changed · + 9 added · ± 285 modified

+ Added

  • builtins/constants.html
  • builtins/exceptions.html
  • builtins/functions.html
  • builtins/index.html
  • builtins/stdtypes.html
  • builtins/threadsafety.html
  • builtins/time-complexity.html
  • c-api/pyexpat.html
  • library/tkinter.dialogs.html

± Modified

  • glossary.html
  • index.html
  • license.html
  • py-modindex.html
  • _static/tachyon-example-heatmap.html
  • c-api/bool.html
  • c-api/buffer.html
  • c-api/bytearray.html
  • c-api/bytes.html
  • c-api/capsule.html
  • and 275 more...
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka serhiy-storchaka mentioned this pull request Sep 1, 2026
Add warning to xml.sax.saxutils.XMLGenerator about untrusted inputs #139478
Open
@serhiy-storchaka
Merge remote-tracking branch 'upstream/main' into pythongh-57092-xmlg…
a3a266c
…en-validate
vstinner
vstinner reviewed Sep 3, 2026
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The overall change LGTM.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/xml/sax/saxutils.py

def startElement(self, name, attrs):
if self._validate:
_check_name(name, 'element name')

@vstinner vstinner Sep 3, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to validate attributes here? With the current code, you start writing before raising an error on invalid attribute. So on error, incomplete XML is written.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@serhiy-storchaka serhiy-storchaka Sep 3, 2026

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not see how can this help? We already wrote something.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Lib/xml/sax/saxutils.py
def startElementNS(self, name, qname, attrs):
name = self._qname(name)
if self._validate:
_check_name(name, 'element name')

@vstinner vstinner Sep 3, 2026

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same remark: can you check attributes here?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@vstinner

vstinner commented Sep 3, 2026

Copy link
Copy Markdown
Member

I wrote a short program to understand how errors are handled and what is written.

from xml.sax.saxutils import XMLGenerator
from io import StringIO

stream = StringIO()
gen = XMLGenerator(stream, validate=True)
gen.startElement('hello', {})
gen.endElement('hello')
try:
    gen.startElement('hello2', {'': 'value'})
except ValueError:
    pass
gen.startElement('hello3', {})
gen.endElement('hello3')
print(stream.getvalue())

With this change, the output is:

<hello></hello><hello2<hello3></hello3>

Ah yes, <hello></hello> is already written.

My concern is that an unfinished <hello2 markup is written because of the validation error (ValueError).

With my suggestion, it would be possible to write:

<hello></hello><hello3></hello3>

I'm fine with not supporting this case and declare game over at the first validation error: the output should be discard in this case.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

vstinner
vstinner approved these changes Sep 3, 2026
View reviewed changes

@vstinner vstinner left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Moving all checks at the function entry would avoid writing unfinished XML markup, but I'm fine with not supporting this case and expect the caller to discard the whole output at the first validation error.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Sep 3, 2026
@serhiy-storchaka

serhiy-storchaka commented Sep 3, 2026

Copy link
Copy Markdown
Member Author

Valid XML should have the root element. If serialization fails, the close tag for the root element and other open elements is no written -- this is an invalid XML. If serialization fails before writing the root element -- this is an invalid XML.

See also #149468. This PR is modeled on PR #149469.

vstinner reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@serhiy-storchaka
Merge remote-tracking branch 'upstream/main' into pythongh-57092-xmlg…
347e135
…en-validate

# Conflicts:
#	Doc/whatsnew/3.16.rst
@bedevere-app bedevere-app Bot added the type-feature A feature request or enhancement label Nov 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@vstinner vstinner vstinner approved these changes
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting merge type-feature A feature request or enhancement

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@serhiy-storchaka @vstinner
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.