xmlsafe 0.5.2

An XML writer that protects you from XML injections through type safety.
Documentation
xmlsafe-0.5.2 has been yanked.

xmlsafe

An XML writer that protects you from XML injections through type safety.

  • three marker traits mark the XML safety of Display implementations

  • the streaming XmlWriter requires its arguments to implement these traits

  • a tag! macro to structure your code (plays well with rustfmt)

If you forget to escape a string, your code just doesn't compile. To prevent XML injections keep two things in mind:

  1. Whenever you supply a string literal (&'static str), take care that it is syntactically valid for the respective context.

  2. Whenever you implement one of the marker traits, take care that you fulfill its requirements.

Example

use std::fmt::Error;
use xmlsafe::{XmlWriter, format_text, escape_text, tag};

struct User {name: String, id: u8}

fn list_users(mut w: XmlWriter, users: Vec<User>) -> Result<(), Error> {
    tag!(w, "div", "class"="users", {
        w.write(format_text!("There are {} users:", users.len()))?;
        tag!(w, "ul", {
            for user in users {
                tag!(w, "li", "data-id"=user.id, {
                    w.write(escape_text(user.name))?;
                });
            }
        });
    });
    Ok(())
}

fn main() {
    let mut out = String::new();
    let users = vec![User{name: "Alice".into(), id: 3}, User{name: "Bob".into(), id: 5}];
    list_users(XmlWriter::new(&mut out), users).unwrap();
    assert_eq!(out, "<div class=\"users\">There are 2 users:\
        <ul><li data-id=\"3\">Alice</li><li data-id=\"5\">Bob</li></ul></div>");
}

Note how the XmlWriter acts as a protective layer between the actual write target (the String in our example) and the XML generation code. Also note that if we forgot the escape_text call, the example would not compile.

Safety

xmlsafe forbids unsafe code and does not panic.