Don't use different escaping rules for attributes
This commit is contained in:
parent
0b531572cf
commit
b1aa300884
3 changed files with 20 additions and 78 deletions
|
@ -7,27 +7,9 @@ use std::fmt::Writer as FmtWriter;
|
|||
|
||||
pub type FmtResult<T> = Result<T, fmt::Error>;
|
||||
|
||||
/// Utilities for escaping HTML5 markup.
|
||||
///
|
||||
/// These follow the *HTML fragment serialization algorithm*, as
|
||||
/// specified by the [HTML 5.1 Working Draft][1].
|
||||
///
|
||||
/// [1]: http://www.w3.org/TR/html51/syntax.html#escapingString
|
||||
pub mod escape {
|
||||
use std::fmt::Writer as FmtWriter;
|
||||
|
||||
use super::render;
|
||||
use super::rt;
|
||||
|
||||
/// Escape a double-quoted attribute value, as per HTML5 rules.
|
||||
pub fn attribute(s: &str) -> String {
|
||||
render(|w| rt::escape_attribute(w, |w| w.write_str(s)))
|
||||
}
|
||||
|
||||
/// Escape non-attribute text content, as per HTML5 rules.
|
||||
pub fn non_attribute(s: &str) -> String {
|
||||
render(|w| rt::escape_non_attribute(w, |w| w.write_str(s)))
|
||||
}
|
||||
/// Escape an HTML value.
|
||||
pub fn escape(s: &str) -> String {
|
||||
render(|w| rt::escape(w, |w| w.write_str(s)))
|
||||
}
|
||||
|
||||
/// Internal functions used by the `maud_macros` package. You should
|
||||
|
@ -38,36 +20,19 @@ pub mod rt {
|
|||
use std::fmt::Writer as FmtWriter;
|
||||
use super::FmtResult;
|
||||
|
||||
struct AttrEscaper<'a, 'b: 'a> {
|
||||
struct Escaper<'a, 'b: 'a> {
|
||||
inner: &'a mut (FmtWriter + 'b),
|
||||
}
|
||||
|
||||
impl<'a, 'b> FmtWriter for AttrEscaper<'a, 'b> {
|
||||
impl<'a, 'b> FmtWriter for Escaper<'a, 'b> {
|
||||
fn write_str(&mut self, s: &str) -> FmtResult<()> {
|
||||
for c in s.chars() {
|
||||
try!(match c {
|
||||
'&' => self.inner.write_str("&"),
|
||||
'\u{A0}' => self.inner.write_str(" "),
|
||||
'"' => self.inner.write_str("""),
|
||||
_ => write!(self.inner, "{}", c),
|
||||
});
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
struct NonAttrEscaper<'a, 'b: 'a> {
|
||||
inner: &'a mut (FmtWriter + 'b),
|
||||
}
|
||||
|
||||
impl<'a, 'b> FmtWriter for NonAttrEscaper<'a, 'b> {
|
||||
fn write_str(&mut self, s: &str) -> FmtResult<()> {
|
||||
for c in s.chars() {
|
||||
try!(match c {
|
||||
'&' => self.inner.write_str("&"),
|
||||
'\u{A0}' => self.inner.write_str(" "),
|
||||
'<' => self.inner.write_str("<"),
|
||||
'>' => self.inner.write_str(">"),
|
||||
'"' => self.inner.write_str("""),
|
||||
'\'' => self.inner.write_str("'"),
|
||||
_ => write!(self.inner, "{}", c),
|
||||
});
|
||||
}
|
||||
|
@ -76,17 +41,10 @@ pub mod rt {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn escape_attribute<F>(w: &mut FmtWriter, f: F) -> FmtResult<()> where
|
||||
pub fn escape<F>(w: &mut FmtWriter, f: F) -> FmtResult<()> where
|
||||
F: FnOnce(&mut FmtWriter) -> FmtResult<()>
|
||||
{
|
||||
f(&mut AttrEscaper { inner: w })
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn escape_non_attribute<F>(w: &mut FmtWriter, f: F) -> FmtResult<()> where
|
||||
F: FnOnce(&mut FmtWriter) -> FmtResult<()>
|
||||
{
|
||||
f(&mut NonAttrEscaper { inner: w })
|
||||
f(&mut Escaper { inner: w })
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,9 +9,8 @@ use super::render::Renderer;
|
|||
|
||||
#[derive(Copy, PartialEq, Show)]
|
||||
pub enum Escape {
|
||||
None,
|
||||
Attr,
|
||||
Body,
|
||||
PassThru,
|
||||
Escape,
|
||||
}
|
||||
|
||||
macro_rules! guard {
|
||||
|
@ -85,14 +84,6 @@ impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
|
|||
self.input = self.input.slice_from(n);
|
||||
}
|
||||
|
||||
fn choose_escape(&self) -> Escape {
|
||||
if self.in_attr {
|
||||
Escape::Attr
|
||||
} else {
|
||||
Escape::Body
|
||||
}
|
||||
}
|
||||
|
||||
/// Construct a Rust AST parser from the given token tree.
|
||||
fn new_rust_parser(&self, tts: Vec<TokenTree>) -> RustParser<'s> {
|
||||
parse::tts_to_parser(self.render.cx.parse_sess, tts, self.render.cx.cfg.clone())
|
||||
|
@ -135,10 +126,7 @@ impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
|
|||
};
|
||||
let lit = self.new_rust_parser(vec![tt.clone()]).parse_lit();
|
||||
match lit_to_string(self.render.cx, lit, minus) {
|
||||
Some(s) => {
|
||||
let escape = self.choose_escape();
|
||||
self.render.string(s.as_slice(), escape);
|
||||
},
|
||||
Some(s) => self.render.string(s.as_slice(), Escape::Escape),
|
||||
None => return false,
|
||||
}
|
||||
true
|
||||
|
@ -148,11 +136,11 @@ impl<'cx: 'r, 's: 'cx, 'i, 'r, 'o: 'r> Parser<'cx, 's, 'i, 'r, 'o> {
|
|||
let (escape, sp) = match self.input {
|
||||
[ref tt @ dollar!(), dollar!(), ..] => {
|
||||
self.shift(2);
|
||||
(Escape::None, tt.get_span())
|
||||
(Escape::PassThru, tt.get_span())
|
||||
},
|
||||
[ref tt @ dollar!(), ..] => {
|
||||
self.shift(1);
|
||||
(self.choose_escape(), tt.get_span())
|
||||
(Escape::Escape, tt.get_span())
|
||||
},
|
||||
_ => return false,
|
||||
};
|
||||
|
|
|
@ -4,8 +4,8 @@ use syntax::ext::base::ExtCtxt;
|
|||
use syntax::parse::token;
|
||||
use syntax::ptr::P;
|
||||
|
||||
use maud;
|
||||
use super::parse::Escape;
|
||||
use maud::escape;
|
||||
|
||||
pub struct Renderer<'cx, 's: 'cx, 'o> {
|
||||
pub cx: &'cx mut ExtCtxt<'s>,
|
||||
|
@ -43,9 +43,8 @@ impl<'cx, 's: 'cx, 'o> Renderer<'cx, 's, 'o> {
|
|||
/// Append a literal string, with the specified escaping method.
|
||||
pub fn string(&mut self, s: &str, escape: Escape) {
|
||||
let s = match escape {
|
||||
Escape::None => s.into_cow(),
|
||||
Escape::Attr => escape::attribute(s).into_cow(),
|
||||
Escape::Body => escape::non_attribute(s).into_cow(),
|
||||
Escape::PassThru => s.into_cow(),
|
||||
Escape::Escape => maud::escape(s).into_cow(),
|
||||
};
|
||||
self.write(s.as_slice());
|
||||
}
|
||||
|
@ -54,13 +53,10 @@ impl<'cx, 's: 'cx, 'o> Renderer<'cx, 's, 'o> {
|
|||
pub fn splice(&mut self, expr: P<Expr>, escape: Escape) {
|
||||
let w = self.w;
|
||||
self.stmts.push(match escape {
|
||||
Escape::None => quote_stmt!(self.cx, try!(write!($w, "{}", $expr))),
|
||||
Escape::Attr =>
|
||||
Escape::PassThru => quote_stmt!(self.cx, try!(write!($w, "{}", $expr))),
|
||||
Escape::Escape =>
|
||||
quote_stmt!(self.cx,
|
||||
try!(::maud::rt::escape_attribute($w, |w| write!(w, "{}", $expr)))),
|
||||
Escape::Body =>
|
||||
quote_stmt!(self.cx,
|
||||
try!(::maud::rt::escape_non_attribute($w, |w| write!(w, "{}", $expr)))),
|
||||
try!(::maud::rt::escape($w, |w| write!(w, "{}", $expr)))),
|
||||
});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue