aboutsummaryrefslogtreecommitdiffstats
path: root/askama_derive/src
diff options
context:
space:
mode:
authorLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-08-02 20:48:41 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2017-08-02 20:48:41 +0200
commit82d85bbc20ec4c525d65c4e12e157a934ac2719e (patch)
tree8d50c8f696e4d092f64e265b3f44804f54001c34 /askama_derive/src
parente1b70fb1b930864094c073a28e47e163ccc99a4e (diff)
downloadaskama-82d85bbc20ec4c525d65c4e12e157a934ac2719e.tar.gz
askama-82d85bbc20ec4c525d65c4e12e157a934ac2719e.tar.bz2
askama-82d85bbc20ec4c525d65c4e12e157a934ac2719e.zip
Fix edge cases in content literal parser (fixes #24)
Diffstat (limited to 'askama_derive/src')
-rw-r--r--askama_derive/src/parser.rs37
1 files changed, 26 insertions, 11 deletions
diff --git a/askama_derive/src/parser.rs b/askama_derive/src/parser.rs
index ce13add..74140bf 100644
--- a/askama_derive/src/parser.rs
+++ b/askama_derive/src/parser.rs
@@ -61,20 +61,35 @@ fn split_ws_parts(s: &[u8]) -> Node {
str::from_utf8(res.2).unwrap())
}
+enum ContentState {
+ Any,
+ Brace(usize),
+ End(usize),
+}
+
fn take_content(i: &[u8]) -> IResult<&[u8], Node> {
- if i.len() < 1 || i[0] == b'{' {
- return IResult::Error(error_position!(nom::ErrorKind::TakeUntil, i));
- }
- for (j, c) in i.iter().enumerate() {
- if *c == b'{' {
- if i.len() < j + 2 {
- return IResult::Done(&i[..0], split_ws_parts(&i[..]));
- } else if i[j + 1] == b'{' || i[j + 1] == b'%' || i[j + 1] == b'#' {
- return IResult::Done(&i[j..], split_ws_parts(&i[..j]));
- }
+ use parser::ContentState::*;
+ let mut state = Any;
+ for (idx, c) in i.iter().enumerate() {
+ state = match (state, *c) {
+ (Any, b'{') => Brace(idx),
+ (Any, _) => Any,
+ (Brace(start), b'{') |
+ (Brace(start), b'%') |
+ (Brace(start), b'#') => End(start),
+ (Brace(_), _) => Any,
+ (End(_), _) => panic!("cannot happen"),
+ };
+ if let End(_) = state {
+ break;
}
}
- IResult::Done(&i[..0], split_ws_parts(&i[..]))
+ match state {
+ Any |
+ Brace(_) => IResult::Done(&i[..0], split_ws_parts(i)),
+ End(0) => IResult::Error(nom::ErrorKind::Custom(0)),
+ End(start) => IResult::Done(&i[start..], split_ws_parts(&i[..start])),
+ }
}
fn identifier(input: &[u8]) -> IResult<&[u8], &str> {