tpt-xml
RustSecurity-first Rust XML toolkit — zero-copy reader/writer, DOM, serde, and an XPath 1.0 subset, with mandatory limits against XXE and entity-expansion attacks.
0 stars0 forks0 watchersApache License 2.0
Languages
Rust100.0%
README
tpt-xml
A dependency-light, security-first XML toolkit, split into small crates that
each do one job well. Modeled structurally on the sibling
tpt-yaml family, but standalone:
nothing here depends on tpt-yaml-* or any tpt-io-* crate.
| Crate | Description |
|---|---|
tpt-xml-core | Zero-copy event/QName/Attribute/namespace types, span, local diagnostics, encoding detection. Zero external dependencies, no_std + alloc + std. |
tpt-xml-security | XmlLimits / LimitState: the resource-limit bookkeeping that guards every parse against XXE and billion-laughs-style entity expansion. |
tpt-xml-reader | Hand-rolled streaming XML tokenizer (Reader/NsReader). No external XML parsing dependency. tpt-xml-security is a mandatory, non-optional dependency. |
tpt-xml-writer | Streaming XML serializer with unconditional escaping. |
tpt-xml-dom | A small in-memory Document/Node tree, built by driving the reader/writer (no independent tokenizer). |
tpt-xml-serde | serde (de)serialization directly over the reader/writer event stream. |
tpt-xml-xpath | A deliberately limited XPath 1.0-ish subset over tpt-xml-dom trees. No XSLT, no XPath 2.0/3.1 — see the "Deferred" section of todo.md. |
Quick start
use tpt_xml_dom::Document;
let doc = Document::parse(b"<root a=\"1\"><child>text</child></root>")?;
let root = doc.root_element().unwrap();
assert_eq!(root.name().local_name(), b"root");
# Ok::<(), tpt_xml_dom::DomError>(())
Design principles
- Security by default. Every
Reader/Writeris constructed withXmlLimits::default(). There is no public path to an unlimited parser except the explicitly-namedXmlLimits::unbounded_trust_this_input()escape hatch, which loudly documents that it disables XXE/billion-laughs protection. - No external entity / external DTD-subset resolution. This is structurally absent from the parser in v1 — not a flag you could accidentally leave on.
- Zero-copy where it matters.
tpt-xml-core::Event<'a>borrows from the input buffer; no owned buffers, no hidden allocations in the hot path. - No dependency on
tpt-io-*or any external XML parsing crate. This is an independent implementation, standalone from the rest of the TPT crate families. - Small, single-purpose crates. Each crate does one job;
tpt-xml-domandtpt-xml-xpathbuild on the reader/writer rather than reimplementing tokenizing or serialization.
Status
Early development. See todo.md for the build checklist and
AGENTS.md for repo conventions (publish order, feature-split
policy, MSRV).
License
Licensed under either of Apache License, Version 2.0 or MIT license at your option.