mozilla / nunjucks

A powerful templating engine with inheritance, asynchronous control, and more (jinja2 inspired)
https://mozilla.github.io/nunjucks/
BSD 2-Clause "Simplified" License
8.48k stars 635 forks source link

Prevent double escape #1390

Open wolframkriesing opened 2 years ago

wolframkriesing commented 2 years ago

I expect to not escape strings multiple times, even when passed through multiple steps. I this case I pass a variable into a block, which gets rendered and set into a variable, that gets then printed. The result is escaped twice, which means " became ".

Below is the test I wrote in tests/compile.js, I also have it failing, but tbh I have no idea how to make it pass. I invested some time trying to understand the generated code, etc. but I failed. Hints would be very much appreciated. If I can get this to become a PR, I would do it, but I need some guidance.

    it('should not escape strings multiple times, even when passed through multiple steps', function() {
      const varWithEscapableChars = '"in quotes" and with <brackets>';
      const tmpl = new Template('{% set inlineVar %}{% block block1 %}{% endblock %}{% endset %} {{ inlineVar }}');
      const multiEscapedString = render('{% extends tmpl %} {% block block1 %}{{ varWithEscapableChars }}{% endblock %}',
        {
          tmpl: tmpl,
          varWithEscapableChars: varWithEscapableChars,
        },
        {autoescape: true}
      );
      const singleEscapedString = render('{{ varWithEscapableChars }}',
        {
          varWithEscapableChars: varWithEscapableChars,
        },
        {autoescape: true}
      );
      expect(multiEscapedString).to.equal(singleEscapedString);
    });

The test fails like so:

Error: expected ' &amp;quot;in quotes&amp;quot; and with &amp;lt;brackets&amp;gt;' to equal '&quot;in quotes&quot; and with &lt;brackets&gt;'