A few kilobytes of internal entities expanded to millions of nodes (each top-level
reference stays under roxmltree's per-reference cap), so a 1 MB file exhausted memory.
SVG keeps DTDs, which Illustrator's exports use for entities, but caps the expanded
document at 4 million nodes. Final Cut Pro XML and FCPXML, which FilmCraft parses
without a node limit, are refused when they declare an entity; real exports never do.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Found while testing crates/svg/src/lib.rs:510-520 (parse_css)
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Every selector of a comma list cloned the whole declaration block, and every
element scanned every rule, so a sub-megabyte <style> could demand billions of
string pairs. Selectors now index one shared block, the sheets are capped at
20 000 selectors and 50 000 declarations, rules are bucketed by id/class/type
so an element checks only candidates, and matching work over all elements is
charged against a 50M-step budget that fails the import instead of doing it.
Depth-limited <use> expansion still let a few kilobytes of branching
references expand to 2^N elements. The parser now counts every element it
converts, <use> copies included, against a budget of max(500 000, twice the
file's own elements) and fails the import with Error::Xml once it is spent.
Targets currently being expanded are tracked, so mutual references stop at
the first repeat instead of nesting to the depth limit.
Fixes#1236
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01N9kwMcw2pYQ5fSjKa3ZPnh
roxmltree recurses per element and overflowed a 2 MiB stack at a few thousand nested
elements (aborting the app). parse() now scans the element depth first and returns
Error::Xml beyond 256 levels.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>