aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar bott <mhpoin@gmail.com>2018-09-07 19:28:21 +0200
committerLibravatar Dirkjan Ochtman <dirkjan@ochtman.nl>2018-09-07 20:09:52 +0200
commit4f2176a3ad2d174c40617c9f3af13b6bd8270b29 (patch)
treef668ac581353be6086b8c95684887b8c1ca56e0c
parent49b0c95f6c60f96ab434efb53a52f1c2e35d1450 (diff)
downloadaskama-4f2176a3ad2d174c40617c9f3af13b6bd8270b29.tar.gz
askama-4f2176a3ad2d174c40617c9f3af13b6bd8270b29.tar.bz2
askama-4f2176a3ad2d174c40617c9f3af13b6bd8270b29.zip
Fix deep nested imports in macro calls
Diffstat (limited to '')
-rw-r--r--askama_derive/src/generator.rs47
-rw-r--r--testing/templates/deep-import-child.html4
-rw-r--r--testing/templates/deep-import-parent.html2
-rw-r--r--testing/templates/deep-nested-macro.html4
-rw-r--r--testing/tests/macro.rs10
5 files changed, 39 insertions, 28 deletions
diff --git a/askama_derive/src/generator.rs b/askama_derive/src/generator.rs
index 81c0e27..07a90e5 100644
--- a/askama_derive/src/generator.rs
+++ b/askama_derive/src/generator.rs
@@ -264,7 +264,7 @@ impl<'a> Generator<'a> {
self.write_loop(ctx, buf, ws1, var, iter, body, ws2);
}
Node::BlockDef(ws1, name, _, ws2) => {
- if let AstLevel::Nested(_) = level {
+ if AstLevel::Nested == level {
panic!(
"blocks ('{}') are only allowed at the top level of a template \
or another block",
@@ -278,7 +278,7 @@ impl<'a> Generator<'a> {
self.handle_include(ctx, buf, ws, path);
}
Node::Call(ws, scope, name, ref args) => {
- self.write_call(ctx, buf, ws, scope, name, args, level);
+ self.write_call(ctx, buf, ws, scope, name, args);
}
Node::Macro(_, ref m) => {
if level != AstLevel::Top {
@@ -325,7 +325,7 @@ impl<'a> Generator<'a> {
}
buf.writeln(" {");
self.locals.push();
- self.handle(ctx, nodes, buf, AstLevel::Nested(None));
+ self.handle(ctx, nodes, buf, AstLevel::Nested);
self.locals.pop();
}
self.handle_ws(buf, ws);
@@ -375,7 +375,7 @@ impl<'a> Generator<'a> {
}
buf.writeln(" => {");
self.handle_ws(buf, ws);
- self.handle(ctx, body, buf, AstLevel::Nested(None));
+ self.handle(ctx, body, buf, AstLevel::Nested);
buf.writeln("}");
self.locals.pop();
}
@@ -406,7 +406,7 @@ impl<'a> Generator<'a> {
}
buf.writeln(&format!(") in (&{}).into_iter().enumerate() {{", expr_code));
- self.handle(ctx, body, buf, AstLevel::Nested(None));
+ self.handle(ctx, body, buf, AstLevel::Nested);
self.handle_ws(buf, ws2);
buf.writeln("}");
self.locals.pop();
@@ -420,22 +420,13 @@ impl<'a> Generator<'a> {
scope: Option<&str>,
name: &str,
args: &[Expr],
- level: AstLevel,
) {
if name == "super" {
self.write_block(buf, None, ws);
return;
}
- let own_scope = match scope {
- None => match level {
- AstLevel::Nested(s) => s,
- _ => None,
- },
- s => s,
- };
-
- let def = if let Some(s) = own_scope {
+ let (def, own_ctx) = if let Some(s) = scope {
let path = ctx
.imports
.get(s)
@@ -444,15 +435,18 @@ impl<'a> Generator<'a> {
.contexts
.get(path)
.unwrap_or_else(|| panic!("context for '{:?}' not found", path));
- mctx.macros
- .get(name)
- .unwrap_or_else(|| panic!("macro '{}' not found in scope '{}'", s, name))
+ (mctx.macros
+ .get(name)
+ .unwrap_or_else(|| panic!("macro '{}' not found in scope '{}'", s, name)),
+ mctx)
} else {
- ctx.macros
- .get(name)
- .unwrap_or_else(|| panic!("macro '{}' not found", name))
+ (ctx.macros
+ .get(name)
+ .unwrap_or_else(|| panic!("macro '{}' not found", name)),
+ ctx)
};
+
self.flush_ws(buf, ws); // Cannot handle_ws() here: whitespace from macro definition comes first
self.locals.push();
buf.writeln("{");
@@ -466,7 +460,8 @@ impl<'a> Generator<'a> {
buf.writeln(&format!("let {} = &{};", arg, expr_code));
self.locals.insert(arg);
}
- self.handle(ctx, &def.nodes, buf, AstLevel::Nested(own_scope));
+
+ self.handle(own_ctx, &def.nodes, buf, AstLevel::Nested);
self.flush_ws(buf, def.ws2);
buf.writeln("}");
@@ -486,7 +481,7 @@ impl<'a> Generator<'a> {
// Since nodes must not outlive the Generator, we instantiate
// a nested Generator here to handle the include's nodes.
let mut gen = self.child();
- gen.handle(ctx, &nodes, buf, AstLevel::Nested(None));
+ gen.handle(ctx, &nodes, buf, AstLevel::Nested);
}
self.prepare_ws(ws);
}
@@ -1018,13 +1013,13 @@ where
}
#[derive(Clone, PartialEq)]
-enum AstLevel<'a> {
+enum AstLevel {
Top,
Block,
- Nested(Option<&'a str>),
+ Nested,
}
-impl<'a> Copy for AstLevel<'a> {}
+impl Copy for AstLevel {}
#[derive(Clone)]
enum DisplayWrap {
diff --git a/testing/templates/deep-import-child.html b/testing/templates/deep-import-child.html
new file mode 100644
index 0000000..268d6d0
--- /dev/null
+++ b/testing/templates/deep-import-child.html
@@ -0,0 +1,4 @@
+{%- import "nested-macro.html" as libi -%}
+{%- macro parent() -%}
+ {% call libi::parent() %}
+{%- endmacro -%}
diff --git a/testing/templates/deep-import-parent.html b/testing/templates/deep-import-parent.html
new file mode 100644
index 0000000..6aa6009
--- /dev/null
+++ b/testing/templates/deep-import-parent.html
@@ -0,0 +1,2 @@
+{%- import "deep-import-child.html" as libj -%}
+{% call libj::parent() %}
diff --git a/testing/templates/deep-nested-macro.html b/testing/templates/deep-nested-macro.html
index 39e8e91..c34dd5f 100644
--- a/testing/templates/deep-nested-macro.html
+++ b/testing/templates/deep-nested-macro.html
@@ -1,2 +1,2 @@
-{%- import "nested-macro.html" as libk -%}
-{%- call libk::parent() -%}
+{%- import "nested-macro.html" as libi -%}
+{%- call libi::parent() -%}
diff --git a/testing/tests/macro.rs b/testing/tests/macro.rs
index 4e43d7c..77e0e59 100644
--- a/testing/tests/macro.rs
+++ b/testing/tests/macro.rs
@@ -36,3 +36,13 @@ fn test_nested() {
let t = NestedTemplate;
assert_eq!(t.render().unwrap(), "foo");
}
+
+#[derive(Template)]
+#[template(path = "deep-import-parent.html")]
+struct DeepImportTemplate;
+
+#[test]
+fn test_deep_import() {
+ let t = DeepImportTemplate;
+ assert_eq!(t.render().unwrap(), "foo");
+}