From b3f0d67ac72fc9f75523efde0eae6c6fd720afb2 Mon Sep 17 00:00:00 2001 From: Daniel Jagszent Date: Fri, 26 Feb 2021 15:58:41 +0100 Subject: [PATCH] add some necessary exceptions to strict_variables = true handling fixes #679 --- src/twig.expression.js | 21 ++++++++++++++++++++- test/test.options.js | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 1 deletion(-) diff --git a/src/twig.expression.js b/src/twig.expression.js index 6c2a1539..4b1c7d3d 100644 --- a/src/twig.expression.js +++ b/src/twig.expression.js @@ -847,7 +847,25 @@ module.exports = function (Twig) { return Twig.expression.resolveAsync.call(state, context[token.value], context) .then(value => { if (state.template.options.strictVariables && value === undefined) { - throw new Twig.Error('Variable "' + token.value + '" does not exist.'); + let skipException = false; + if (token.peek) { + const {peek} = token; + if (peek.type === Twig.expression.type.filter && peek.value === 'default') { + skipException = true; + } + + if (peek.type === Twig.expression.type.operator.binary && peek.value === '??') { + skipException = true; + } + + if (peek.type === Twig.expression.type.test && peek.filter === 'defined') { + skipException = true; + } + } + + if (!skipException) { + throw new Twig.Error('Variable "' + token.value + '" does not exist.'); + } } stack.push(value); @@ -1255,6 +1273,7 @@ module.exports = function (Twig) { while (tokens.length > 0) { token = tokens.shift(); + token.peek = tokens[0]; tokenTemplate = Twig.expression.handler[token.type]; Twig.log.trace('Twig.expression.compile: ', 'Compiling ', token); diff --git a/test/test.options.js b/test/test.options.js index 0481c8f1..5caa76d4 100644 --- a/test/test.options.js +++ b/test/test.options.js @@ -82,4 +82,36 @@ describe('Twig.js Optional Functionality ->', function () { } }); }); + + describe('should not throw an error when `strict_variables` set to `true`', function () { + const filter = twig({ + rethrow: true, + strict_variables: true, + data: '{{ test|default }}' + }); + + const nullcoalescing = twig({ + rethrow: true, + strict_variables: true, + data: '{{ test ?? \'test\' }}' + }); + + const test = twig({ + rethrow: true, + strict_variables: true, + data: '{% if test is defined %}{% endif %}' + }); + + it('For undefined variables with default filter', function () { + filter.render(); + }); + + it('For undefined variables with ?? operator', function () { + nullcoalescing.render(); + }); + + it('For undefined variables with defined test', function () { + test.render(); + }); + }); });