aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--Cargo.lock7
-rw-r--r--askama/Cargo.toml1
-rw-r--r--askama/src/filters.rs50
3 files changed, 47 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 4296551..6e26567 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -10,7 +10,6 @@ dependencies = [
name = "askama"
version = "0.1.0"
dependencies = [
- "htmlescape 0.3.1 (git+https://github.com/veddan/rust-htmlescape)",
"nom 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -24,11 +23,6 @@ dependencies = [
]
[[package]]
-name = "htmlescape"
-version = "0.3.1"
-source = "git+https://github.com/veddan/rust-htmlescape#1699b539179798e705ad8464128492a0a0092876"
-
-[[package]]
name = "nom"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -53,7 +47,6 @@ version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[metadata]
-"checksum htmlescape 0.3.1 (git+https://github.com/veddan/rust-htmlescape)" = "<none>"
"checksum nom 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e5d4598834859fedb9a0a69d5b862a970e77982a92f544d547257a4d49469067"
"checksum quote 0.3.12 (registry+https://github.com/rust-lang/crates.io-index)" = "e7b44fd83db28b83c1c58187159934906e5e955c812e211df413b76b03c909a5"
"checksum syn 0.11.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f4f94368aae82bb29656c98443a7026ca931a659e8d19dcdc41d6e273054e820"
diff --git a/askama/Cargo.toml b/askama/Cargo.toml
index 55c6059..2f28018 100644
--- a/askama/Cargo.toml
+++ b/askama/Cargo.toml
@@ -8,6 +8,5 @@ license = "MIT/Apache-2.0"
workspace = ".."
[dependencies]
-htmlescape = { git = "https://github.com/veddan/rust-htmlescape" }
nom = "2.1"
syn = "0.11"
diff --git a/askama/src/filters.rs b/askama/src/filters.rs
index 08feed3..fd8222c 100644
--- a/askama/src/filters.rs
+++ b/askama/src/filters.rs
@@ -1,8 +1,52 @@
-extern crate htmlescape;
-
use std::fmt;
+fn escapable(b: &u8) -> bool {
+ *b == b'<' || *b == b'>' || *b == b'&'
+}
+
pub fn e(s: &fmt::Display) -> String {
let s = format!("{}", s);
- htmlescape::encode_minimal(&s)
+ let mut found = Vec::new();
+ for (i, b) in s.as_bytes().iter().enumerate() {
+ if escapable(b) {
+ found.push(i);
+ }
+ }
+ if found.is_empty() {
+ return s;
+ }
+
+ let bytes = s.as_bytes();
+ let max_len = bytes.len() + found.len() * 3;
+ let mut res = Vec::<u8>::with_capacity(max_len);
+ let mut start = 0;
+ for idx in &found {
+ if start < *idx {
+ res.extend(&bytes[start..*idx]);
+ }
+ start = *idx + 1;
+ match bytes[*idx] {
+ b'<' => { res.extend(b"&lt;"); },
+ b'>' => { res.extend(b"&gt;"); },
+ b'&' => { res.extend(b"&amp;"); },
+ _ => panic!("incorrect indexing"),
+ }
+ }
+ if start < bytes.len() - 1 {
+ res.extend(&bytes[start..]);
+ }
+
+ String::from_utf8(res).unwrap()
+}
+
+#[cfg(test)]
+mod tests {
+ use super::e;
+ #[test]
+ fn test_escape() {
+ assert_eq!(e(&""), "");
+ assert_eq!(e(&"<&>"), "&lt;&amp;&gt;");
+ assert_eq!(e(&"bla&"), "bla&amp;");
+ assert_eq!(e(&"<foo"), "&lt;foo");
+ }
}