interpreter.getContext().getImportPathStack().push(path, tagNode.getLineNumber(), tagNode.getStartPosition()); } catch (ImportTagCycleException e) { interpreter.addError(new TemplateError(ErrorType.WARNING, ErrorReason.EXCEPTION, ErrorItem.TAG, "Import cycle detected for path: '" + path + "'", null, tagNode.getLineNumber(), tagNode.getStartPosition(), e, BasicTemplateErrorCategory.IMPORT_CYCLE_DETECTED, ImmutableMap.of("path", path))); String templateFile = interpreter.resolveString(path, tagNode.getLineNumber(), tagNode.getStartPosition()); interpreter.getContext().addDependency("coded_files", templateFile); try { String template = interpreter.getResource(templateFile); Node node = interpreter.parse(template); interpreter.render(node); } else { JinjavaInterpreter child = new JinjavaInterpreter(interpreter); child.render(node); interpreter.addAllErrors(child.getErrorsCopy()); Map<String, Object> childBindings = child.getContext().getSessionBindings(); for (Map.Entry<String, MacroFunction> macro : child.getContext().getGlobalMacros().entrySet()) { childBindings.put(macro.getKey(), macro.getValue()); interpreter.getContext().put(contextVar, childBindings);
@Test public void itRecordsFilterNames() { Object val = interpreter.resolveELExpression("2.3 | round", -1); assertThat(val).isEqualTo(new BigDecimal(2)); assertThat(interpreter.getContext().wasValueResolved("filter:round")).isTrue(); }
@Test public void itBlocksDisabledTags() { Map<Context.Library, Set<String>> disabled = ImmutableMap.of(Context.Library.TAG, ImmutableSet.of("raw")); assertThat(interpreter.render("{% raw %}foo{% endraw %}")).isEqualTo("foo"); try (JinjavaInterpreter.InterpreterScopeClosable c = interpreter.enterScope(disabled)) { interpreter.render("{% raw %} foo {% endraw %}"); } TemplateError e = interpreter.getErrorsCopy().get(0); assertThat(e.getItem()).isEqualTo(ErrorItem.TAG); assertThat(e.getReason()).isEqualTo(ErrorReason.DISABLED); assertThat(e.getMessage()).contains("'raw' is disabled in this context"); }
@Override public String interpret(TagNode tagNode, JinjavaInterpreter interpreter) { String macroExpr = "{{" + tagNode.getHelpers().trim() + "}}"; try (InterpreterScopeClosable c = interpreter.enterScope()) { LinkedHashMap<String, Object> args = new LinkedHashMap<>(); MacroFunction caller = new MacroFunction(tagNode.getChildren(), "caller", args, false, false, true, interpreter.getContext()); interpreter.getContext().addGlobalMacro(caller); return interpreter.render(macroExpr); } }
Context context = new Context(globalContext, bindings, renderConfig.getDisabled()); JinjavaInterpreter parentInterpreter = JinjavaInterpreter.getCurrent(); if (parentInterpreter != null) { renderConfig = parentInterpreter.getConfig(); JinjavaInterpreter interpreter = new JinjavaInterpreter(this, context, renderConfig); JinjavaInterpreter.pushCurrent(interpreter); String result = interpreter.render(template); return new RenderResult(result, interpreter.getContext(), interpreter.getErrorsCopy()); } catch (InterpretException e) { if (e instanceof TemplateSyntaxException) { return new RenderResult(TemplateError.fromException((TemplateSyntaxException) e), interpreter.getContext(), interpreter.getErrorsCopy()); return new RenderResult(TemplateError.fromSyntaxError(e), interpreter.getContext(), interpreter.getErrorsCopy()); } catch (Exception e) { return new RenderResult(TemplateError.fromException(e), interpreter.getContext(), interpreter.getErrorsCopy()); } finally { globalContext.reset(); JinjavaInterpreter.popCurrent();
@Override public Object doEvaluate(Map<String, Object> argMap, Map<String, Object> kwargMap, List<Object> varArgs) { JinjavaInterpreter interpreter = JinjavaInterpreter.getCurrent(); try (InterpreterScopeClosable c = interpreter.enterScope()) { for (Map.Entry<String, Object> scopeEntry : localContextScope.getScope().entrySet()) { if (scopeEntry.getValue() instanceof MacroFunction) { interpreter.getContext().addGlobalMacro((MacroFunction) scopeEntry.getValue()); } else { interpreter.getContext().put(scopeEntry.getKey(), scopeEntry.getValue()); } } // named parameters for (Map.Entry<String, Object> argEntry : argMap.entrySet()) { interpreter.getContext().put(argEntry.getKey(), argEntry.getValue()); } // parameter map interpreter.getContext().put("kwargs", kwargMap); // varargs list interpreter.getContext().put("varargs", varArgs); LengthLimitingStringBuilder result = new LengthLimitingStringBuilder(interpreter.getConfig().getMaxOutputSize()); for (Node node : content) { result.append(node.render(interpreter)); } return result.toString(); } }
@Before public void setup() { interpreter = new Jinjava().newInterpreter(); JinjavaInterpreter.pushCurrent(interpreter); context = interpreter.getContext(); }
@Test public void itWillNotReturnClassObjects() { context.put("myobj", new MyClass(new Date(0))); interpreter.resolveELExpression("myobj.getClass()", -1); assertThat(interpreter.getErrorsCopy()).isNotEmpty(); TemplateError e = interpreter.getErrorsCopy().get(0); assertThat(e.getMessage()).contains("Cannot find method 'getClass'"); }
@Test public void enterScopeTryFinally() { interpreter.getContext().put("foo", "parent"); interpreter.enterScope(); try { interpreter.getContext().put("foo", "child"); assertThat(interpreter.resolveELExpression("foo", 1)).isEqualTo("child"); } finally { interpreter.leaveScope(); } assertThat(interpreter.resolveELExpression("foo", 1)).isEqualTo("parent"); }
@Test public void itAvoidsSimpleImportCycle() throws IOException { Jinjava jinjava = new Jinjava(); interpreter = new JinjavaInterpreter(jinjava, context, jinjava.getGlobalConfig()); interpreter.render(Resources.toString(Resources.getResource("tags/importtag/imports-self.jinja"), StandardCharsets.UTF_8)); assertThat(context.get("c")).isEqualTo("hello"); assertThat(interpreter.getErrorsCopy().get(0).getMessage()).contains("Rendering cycle detected:", "imports-self.jinja"); }
Object collection = interpreter.resolveELExpression(loopExpr, tagNode.getLineNumber()); ForLoop loop = ObjectIterator.getLoop(collection); try (InterpreterScopeClosable c = interpreter.enterScope()) { if (loop.getLength() == 0 && interpreter.isValidationMode()) { loop = ObjectIterator.getLoop(0); interpreter.getContext().setValidationMode(true); interpreter.getContext().put(LOOP, loop); LengthLimitingStringBuilder buff = new LengthLimitingStringBuilder(interpreter.getConfig().getMaxOutputSize()); while (loop.hasNext()) { Object val = interpreter.wrap(loop.next()); interpreter.getContext().put(loopVars.get(0), val); } else { for (String loopVar : loopVars) { interpreter.getContext().put(loopVar, entryVal); } else { try { for (PropertyDescriptor valProp : valProps) { if (loopVar.equals(valProp.getName())) { interpreter.getContext().put(loopVar, valProp.getReadMethod().invoke(val)); break; if (interpreter.getContext().isValidationMode()) {
@Test public void enterScopeTryWithResources() { interpreter.getContext().put("foo", "parent"); try (InterpreterScopeClosable c = interpreter.enterScope()) { interpreter.getContext().put("foo", "child"); assertThat(interpreter.resolveELExpression("foo", 1)).isEqualTo("child"); } assertThat(interpreter.resolveELExpression("foo", 1)).isEqualTo("parent"); }
@Test public void itAllowsMacroRecursionWhenEnabledInConfiguration() throws IOException { // I need a different configuration here therefore interpreter = new Jinjava(JinjavaConfig.newBuilder().withEnableRecursiveMacroCalls(true).build()).newInterpreter(); JinjavaInterpreter.pushCurrent(interpreter); try { String template = fixtureText("ending-recursion"); String out = interpreter.render(template); assertThat(interpreter.getErrorsCopy()).isEmpty(); assertThat(out).contains("Hello Hello Hello Hello Hello"); } finally { // and I need to cleanup my mess... JinjavaInterpreter.popCurrent(); } }
@Before public void setup() { validationFilter = new ValidationFilter(); ELFunctionDefinition validationFunction = new ELFunctionDefinition("", "validation_test", ValidationModeTest.class, "validationTestFunction"); jinjava = new Jinjava(); jinjava.getGlobalContext().registerFilter(validationFilter); jinjava.getGlobalContext().registerFunction(validationFunction); interpreter = jinjava.newInterpreter(); context = interpreter.getContext(); validatingInterpreter = new JinjavaInterpreter(jinjava, context, JinjavaConfig.newBuilder().withValidationMode(true).build()); JinjavaInterpreter.pushCurrent(interpreter); }
@Test public void itBlocksDisabledFilters() { Map<Context.Library, Set<String>> disabled = ImmutableMap.of(Context.Library.FILTER, ImmutableSet.of("truncate")); assertThat(interpreter.resolveELExpression("\"hey\"|truncate(2)", -1)).isEqualTo("h..."); try (JinjavaInterpreter.InterpreterScopeClosable c = interpreter.enterScope(disabled)) { interpreter.resolveELExpression("\"hey\"|truncate(2)", -1); TemplateError e = interpreter.getErrorsCopy().get(0); assertThat(e.getItem()).isEqualTo(ErrorItem.FILTER); assertThat(e.getReason()).isEqualTo(ErrorReason.DISABLED); assertThat(e.getMessage()).contains("truncate' is disabled in this context"); } }
@Test public void bubbleUpDependenciesFromLowerScope() { String dependencyType = "foo"; String dependencyIdentifier = "123"; interpreter.enterScope(); interpreter.getContext().addDependency(dependencyType, dependencyIdentifier); assertThat(interpreter.getContext().getDependencies().get(dependencyType)).contains(dependencyIdentifier); interpreter.leaveScope(); assertThat(interpreter.getContext().getDependencies().get(dependencyType)).contains(dependencyIdentifier); }
@Test public void resolveBlockStubsWithSpecialChars() { interpreter.addBlock("foobar", Lists.newLinkedList(Lists.newArrayList(new TextNode(new TextToken("$150.00", -1, -1))))); String content = "this is {% block foobar %}foobar{% endblock %}!"; assertThat(interpreter.render(content)).isEqualTo("this is $150.00!"); }
@Test public void itHandlesVarsAndLiterals() throws Exception { interpreter.getContext().put("d", d); interpreter.getContext().put("foo", "%Y-%m"); assertThat(interpreter.renderFlat("{{ d|datetimeformat(foo) }}")).isEqualTo("2013-11"); assertThat(interpreter.renderFlat("{{ d|datetimeformat(\"%Y-%m-%d\") }}")).isEqualTo("2013-11-06"); assertThat(interpreter.getErrorsCopy()).isEmpty(); }
@After public void tearDown() { JinjavaInterpreter.popCurrent(); }
@Test public void itDoesNotExecuteFiltersInValidatedBlocks() { assertThat(validationFilter.getExecutionCount()).isEqualTo(0); String template = "{{ 10|validation_filter() }}" + "{% if false %}" + " {{ 10|validation_filter() }}" + " {{ hey( }}" + "{% endif %}"; String result = interpreter.render(template).trim(); assertThat(interpreter.getErrors()).isEmpty(); assertThat(result).isEqualTo("10"); assertThat(validationFilter.getExecutionCount()).isEqualTo(1); JinjavaInterpreter.pushCurrent(validatingInterpreter); result = validatingInterpreter.render(template).trim(); assertThat(validatingInterpreter.getErrors().size()).isEqualTo(1); assertThat(validatingInterpreter.getErrors().get(0).getMessage()).contains("hey("); assertThat(result).isEqualTo("10"); assertThat(validationFilter.getExecutionCount()).isEqualTo(2); }