Skip to content

feat: add Python typing stubs, strict mypy CI, and parser security/conformance fixes - #24

Merged
nth-bailey merged 4 commits into
mainfrom
feat/typing-and-bug-fixes
Oct 27, 2026
Merged

nth-bailey merged 4 commits into
mainfrom
feat/typing-and-bug-fixes

Conversation

@nth-bailey

@nth-bailey nth-bailey commented Oct 27, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Closes #20.

1. Strict Python Typing (mypy --strict) & Google Style Enforcement (ruff)

2. 100% Code Coverage for Both Python and Rust (Enforced in CI)

  • Python: 100.00% statement and branch coverage (303 Stmts, 0 Miss, 54 Branch, 0 BrPart, 100%), enforced via pytest --cov=safexml --cov-branch --cov-fail-under=100.
  • Rust: 100.00% line and function coverage (2,411 Lines, 0 Miss, 101 Functions, 0 Miss, 100.00%) across src/doctype.rs, src/parser.rs, and src/python.rs, enforced in .github/workflows/ci.yml via llvm-cov.

3. Security & Conformance Bug Fixes (Broad Bug Sweeps)

  1. ATTLIST Default Attribute Security Bypass (src/parser.rs): Enforced null-byte checks, is_valid_xml_qname, max_name_size, max_attribute_size, max_attributes, max_text_size, < rejection, character validation, whitespace normalization, and entity unescaping on <!ATTLIST> default attributes.
  2. External <!NOTATION> and Parameter Entity (%pe;) Bypass in DTD (src/doctype.rs, src/parser.rs): Parsed <!NOTATION> declarations and %pe; references in internal subsets; enforced ExternalReferenceForbidden and EntitiesForbidden.
  3. Multi-Colon QName Validation (src/parser.rs): Fixed is_valid_xml_qname to reject QNames containing multiple colons (e.g. <p:a:b/>).
  4. Numeric Character Reference + Sign & Malformed &...; in Attributes (src/parser.rs): Rejected &#+65; / &#x+41; per W3C XML 1.0 [66] CharRef and rejected malformed attribute entity names before checking forbid_entities.
  5. Processing Instruction Size Limit & ASCII Whitespace (src/parser.rs): Enforced max_comment_size on Event::PI payloads and split PI target using strict XML whitespace (is_xml_whitespace).
  6. Streaming XMLParser.feed() Input Size Limit (python/safexml/ElementTree.py): Enforced max_input_size immediately during feed() before buffering unbounded chunks in memory, and prevented post-close() buffer accumulation.
  7. Deep Tree Recursion Elimination in Python Wrappers (python/safexml/ElementTree.py, python/safexml/minidom.py, python/safexml/sax.py): Converted recursive tree traversals in XMLParser, minidom._element_to_dom, and sax._replay_element to explicit iterative stacks so trees with max_depth > 1000 never raise RecursionError.
  8. Strict forbid_dtd / forbid_entities / forbid_external Parity Across All Entrypoints (python/safexml/__init__.py, python/safexml/ElementTree.py): Added missing security parameters to safexml.parse, safexml.fromstring, ElementTree.iterparse, and XMLParser.

@nth-bailey
nth-bailey merged commit 5506fa1 into main Oct 27, 2026
19 checks passed
@nth-bailey
nth-bailey deleted the feat/typing-and-bug-fixes branch October 27, 2026 18:05
github-actions Bot pushed a commit that referenced this pull request Oct 27, 2026
# [1.2.0](v1.1.1...v1.2.0) (2026-10-27)

### Features

* add Python typing stubs, strict mypy CI, and parser security/conformance fixes ([#24](#24)) ([5506fa1](5506fa1))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[FEAT]: Add Python typing

1 participant