tpt-xml

Rust

Security-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.

CrateDescription
tpt-xml-coreZero-copy event/QName/Attribute/namespace types, span, local diagnostics, encoding detection. Zero external dependencies, no_std + alloc + std.
tpt-xml-securityXmlLimits / LimitState: the resource-limit bookkeeping that guards every parse against XXE and billion-laughs-style entity expansion.
tpt-xml-readerHand-rolled streaming XML tokenizer (Reader/NsReader). No external XML parsing dependency. tpt-xml-security is a mandatory, non-optional dependency.
tpt-xml-writerStreaming XML serializer with unconditional escaping.
tpt-xml-domA small in-memory Document/Node tree, built by driving the reader/writer (no independent tokenizer).
tpt-xml-serdeserde (de)serialization directly over the reader/writer event stream.
tpt-xml-xpathA 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/Writer is constructed with XmlLimits::default(). There is no public path to an unlimited parser except the explicitly-named XmlLimits::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-dom and tpt-xml-xpath build 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.