0.5.3 |
|
---|---|
0.5.2 |
|
0.4.0 |
|
0.3.0 |
|
0.1.0 |
|
#86 in #string-literal
25KB
410 lines
xmlsafe
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 withrustfmt
)
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.
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.