Crates.io | xmlsafe |
lib.rs | xmlsafe |
version | 0.5.3 |
source | src |
created_at | 2021-08-14 22:31:29.069941 |
updated_at | 2021-08-28 06:04:38.45702 |
description | A streaming XML writer that protects you from XML injections through type safety. |
homepage | |
repository | https://git.push-f.com/xmlsafe |
max_upload_size | |
id | 437006 |
size | 24,635 |
A streaming XML writer that:
prevents accidental XML injections by requiring its arguments to implement specific traits
provides a tag!
macro to structure your code
(designed to play well with rustfmt
)
If you forget to escape a string, your code just doesn't compile. To be safe from XML injections keep two things in mind:
Whenever you supply a string literal (&'static str
), take care
that it is syntactically valid for the respective context.
Whenever you implement one of the traits, take care that you fulfill its requirements.
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.
xmlsafe forbids unsafe
code and does not panic.