Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Default escaping in Freemarker

In Freemarker templates we can use the escape directive to automatically apply an escaping to all interpolations inside the included block:

<#escape x as x?html>
  <#-- name is escaped as html -->
  Hallo, ${name}
</#escape>

Is there a way to programmatically achieve a similar effect, defining a default escape applied to all interpolations in the template, including those outside escape directives?

Thanks.

like image 988
Massimiliano Fliri Avatar asked Aug 12 '09 10:08

Massimiliano Fliri


2 Answers

To elaborate on Attila's answer: you can use a class like this one and then wrap your template loader like this:

final TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), templatePath) {
  /**
   * Replaces the normal template reader with something that changes the default
   * escaping to HTML as to avoid XSS attacks.
   */
  @Override
  public Reader getReader(Object templateSource, String encoding) throws IOException {
     return new WrappingReader(super.getReader(templateSource, encoding), "<#escape x as x?html>", "</#escape>");
  }
};

If you don't include linebreaks in the added parts you don't get the line numbering problem. You can't use the <#ftl>/[#ftl] with this approach, though.

like image 92
Peter Becker Avatar answered Oct 11 '22 20:10

Peter Becker


Since 2.3.24 each template has an associated freemarker.core.OutputFormat object, which specifies if and how ${...} (and #{...}) is escaped. OuputFormat for HTML, XML and RTF are provided out of the box, but you can also define your own formats. When the selected OutputFormat escapes by default, then you can prevent escaping explicitly like ${foo?no_esc}.

There are several ways of associating templates with the OutputFormat you want. For HTML and XML escaping, the recommended way is setting the recognize_standard_file_extensions configuration setting to true, then using ftlh file extension for HTML, and ftlx file extension for XML templates. You can also associate OutputFormat-s to templates based on arbitrary template name (template path) patterns, using the template_configurers setting. Last not least, you can just set the default output format globally like configuration.setOutputFormat(HTMLOutputFormat.INSTANCE). You can also override the output format at the top of the template as <#ftl output_format='HTML'>, though it should be used rarely.

Related documentation pages: http://freemarker.org/docs/dgui_misc_autoescaping.html, http://freemarker.org/docs/pgui_config_outputformatsautoesc.html

like image 26
ddekany Avatar answered Oct 11 '22 20:10

ddekany