diff --git a/src/jinjaturtle/cli.py b/src/jinjaturtle/cli.py index 8158cf4..ce096c4 100644 --- a/src/jinjaturtle/cli.py +++ b/src/jinjaturtle/cli.py @@ -2,6 +2,7 @@ from __future__ import annotations import argparse import sys +from defusedxml import defuse_stdlib from pathlib import Path from .core import ( @@ -47,6 +48,7 @@ def _build_arg_parser() -> argparse.ArgumentParser: def _main(argv: list[str] | None = None) -> int: + defuse_stdlib() parser = _build_arg_parser() args = parser.parse_args(argv) diff --git a/src/jinjaturtle/core.py b/src/jinjaturtle/core.py index 5541b61..5da35af 100644 --- a/src/jinjaturtle/core.py +++ b/src/jinjaturtle/core.py @@ -2,10 +2,10 @@ from __future__ import annotations import configparser import json +import xml.etree.ElementTree as ET # nosec import yaml from collections import Counter, defaultdict -from defusedxml import ElementTree as ET from pathlib import Path from typing import Any, Iterable @@ -103,8 +103,7 @@ def parse_config(path: Path, fmt: str | None = None) -> tuple[str, Any]: if fmt == "xml": text = path.read_text(encoding="utf-8") - parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=False)) - root = ET.fromstring(text, parser=parser) + root = ET.fromstring(text) # nosec B314 return fmt, root raise ValueError(f"Unsupported config format: {fmt}") @@ -868,8 +867,10 @@ def _generate_xml_template_from_text(role_prefix: str, text: str) -> str: prolog, body = _split_xml_prolog(text) # Parse with comments included so are preserved - parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True)) - root = ET.fromstring(body, parser=parser) + # defusedxml.defuse_stdlib() is called in CLI entrypoint + parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=True)) # nosec B314 + parser.feed(body) + root = parser.close() _apply_jinja_to_xml_tree(role_prefix, root) diff --git a/tests/test_core.py b/tests/test_core.py index ba692cb..53e979c 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -1,11 +1,11 @@ from __future__ import annotations -from defusedxml import ElementTree as ET from pathlib import Path import configparser import pytest import textwrap import yaml +import xml.etree.ElementTree as ET import jinjaturtle.core as core from jinjaturtle.core import ( @@ -566,8 +566,7 @@ def test_generate_template_xml_structural_fallback(): """ ) - parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=False)) - root = ET.fromstring(xml_text, parser=parser) + root = ET.fromstring(xml_text) tmpl = generate_template("xml", parsed=root, role_prefix="role") @@ -643,8 +642,7 @@ def test_flatten_xml_text_with_attributes_uses_value_suffix(): the text at path + ('value',), not just path. """ xml_text = "text" - parser = ET.XMLParser(target=ET.TreeBuilder(insert_comments=False)) - root = ET.fromstring(xml_text, parser=parser) + root = ET.fromstring(xml_text) items = flatten_config("xml", root)