From f0c80e854f3597c8eb48063ad205842a721da60c Mon Sep 17 00:00:00 2001 From: Ram Kaniyur Date: Thu, 30 May 2019 08:43:22 +1000 Subject: Change askama_escape to require UTF-8 strings --- askama_escape/src/lib.rs | 49 ++++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 24 deletions(-) diff --git a/askama_escape/src/lib.rs b/askama_escape/src/lib.rs index 01da4ed..62a29da 100644 --- a/askama_escape/src/lib.rs +++ b/askama_escape/src/lib.rs @@ -1,5 +1,4 @@ -use std::fmt::{self, Display, Formatter}; -use std::io::{self, prelude::*}; +use std::fmt::{self, Display, Formatter, Write}; use std::str; pub struct MarkupDisplay @@ -53,40 +52,33 @@ where }, "{}", t - ) - .map_err(|_| fmt::Error), + ), DisplayValue::Safe(ref t) => t.fmt(fmt), } } } -pub struct EscapeWriter<'a, 'b: 'a, E> { - fmt: &'a mut fmt::Formatter<'b>, +pub struct EscapeWriter<'a, E, W> { + fmt: W, escaper: &'a E, } -impl io::Write for EscapeWriter<'_, '_, E> +impl<'a, E, W> Write for EscapeWriter<'a, E, W> where + W: Write, E: Escaper, { - fn write(&mut self, bytes: &[u8]) -> io::Result { - self.escaper - .write_escaped_bytes(self.fmt, bytes) - .map_err(|e| io::Error::new(io::ErrorKind::Other, e.to_string()))?; - Ok(bytes.len()) - } - - fn flush(&mut self) -> std::io::Result<()> { - Ok(()) + fn write_str(&mut self, s: &str) -> fmt::Result { + self.escaper.write_escaped(&mut self.fmt, s) } } -pub fn escape(s: &str, escaper: E) -> Escaped<'_, E> +pub fn escape(string: &str, escaper: E) -> Escaped<'_, E> where E: Escaper, { Escaped { - bytes: s.as_bytes(), + string, escaper, } } @@ -95,7 +87,7 @@ pub struct Escaped<'a, E> where E: Escaper, { - bytes: &'a [u8], + string: &'a str, escaper: E, } @@ -104,7 +96,7 @@ where E: Escaper, { fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { - self.escaper.write_escaped_bytes(fmt, self.bytes) + self.escaper.write_escaped(fmt, self.string) } } @@ -121,7 +113,11 @@ macro_rules! escaping_body { } impl Escaper for Html { - fn write_escaped_bytes(&self, fmt: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result { + fn write_escaped(&self, mut fmt: W, string: &str) -> fmt::Result + where + W: Write, + { + let bytes = string.as_bytes(); let mut start = 0; for (i, b) in bytes.iter().enumerate() { if b.wrapping_sub(b'"') <= FLAG { @@ -143,8 +139,11 @@ impl Escaper for Html { pub struct Text; impl Escaper for Text { - fn write_escaped_bytes(&self, fmt: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result { - fmt.write_str(unsafe { str::from_utf8_unchecked(bytes) }) + fn write_escaped(&self, mut fmt: W, string: &str) -> fmt::Result + where + W: Write, + { + fmt.write_str(string) } } @@ -158,7 +157,9 @@ where } pub trait Escaper { - fn write_escaped_bytes(&self, fmt: &mut fmt::Formatter<'_>, bytes: &[u8]) -> fmt::Result; + fn write_escaped(&self, fmt: W, string: &str) -> fmt::Result + where + W: Write; } const FLAG: u8 = b'>' - b'"'; -- cgit