Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Escape output by default #8

Merged
merged 4 commits into from Dec 11, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 42 additions & 2 deletions demos/node_express/public/vendor/twig.js
Expand Up @@ -494,6 +494,7 @@ var Twig = (function (Twig) {

case Twig.token.type.output:
Twig.expression.compile.apply(this, [token]);
Twig.autoescape.apply(this, [token]);
if (stack.length > 0) {
intermediate_output.push(token);
} else {
Expand Down Expand Up @@ -619,6 +620,40 @@ var Twig = (function (Twig) {
return tokens;
};

/**
* Autoescape the output token if needed
*
* @param {Object} data The output token.
*
* @return {Object} The modified token.
*/
Twig.autoescape = function(token) {
if (!this.options.autoescape) {
return token;
}

var raw_found = false;
var current_token;
for (var i=0, l=token.stack.length; i<l; i++) {
current_token = token.stack[i];
if (current_token.type === Twig.expression.type.filter
&& ["raw", "escape", "e"].indexOf(current_token.value) > -1) {
raw_found = true;
break;
}
}

if (!raw_found) {
token.stack.push({
type: Twig.expression.type.filter,
value: "escape",
match: ["|escape", "escape"]
});
}

return token;
}

// Namespace for template storage and retrieval
Twig.Templates = {
registry: {}
Expand Down Expand Up @@ -1907,9 +1942,11 @@ var Twig = (function (Twig) {
return token;
},
parse: function (token, context, chain) {
var output = '';
var output = '',
// Parse the expression
result = Twig.expression.parse.apply(this, [token.stack, context]);

if (chain && Twig.expression.parse.apply(this, [token.stack, context]) === true) {
if (chain && result) {
chain = false;
// parse if output
output = Twig.parse.apply(this, [token.output, context]);
Expand Down Expand Up @@ -4939,6 +4976,7 @@ var Twig = (function (Twig) {
template = '';
}
return new Twig.Template({
options: this.options,
data: template
});
}
Expand Down Expand Up @@ -5047,6 +5085,8 @@ var Twig = (function (Twig) {
var id = params.id,
options = {
strict_variables: params.strict_variables || false,
// TODO: turn autoscape on in the next major version
autoescape: params.autoescape != null && params.autoescape || false,
allowInlineIncludes: params.allowInlineIncludes || false,
rethrow: params.rethrow || false
};
Expand Down
44 changes: 42 additions & 2 deletions demos/twitter_backbone/vendor/twig.js
Expand Up @@ -494,6 +494,7 @@ var Twig = (function (Twig) {

case Twig.token.type.output:
Twig.expression.compile.apply(this, [token]);
Twig.autoescape.apply(this, [token]);
if (stack.length > 0) {
intermediate_output.push(token);
} else {
Expand Down Expand Up @@ -619,6 +620,40 @@ var Twig = (function (Twig) {
return tokens;
};

/**
* Autoescape the output token if needed
*
* @param {Object} data The output token.
*
* @return {Object} The modified token.
*/
Twig.autoescape = function(token) {
if (!this.options.autoescape) {
return token;
}

var raw_found = false;
var current_token;
for (var i=0, l=token.stack.length; i<l; i++) {
current_token = token.stack[i];
if (current_token.type === Twig.expression.type.filter
&& ["raw", "escape", "e"].indexOf(current_token.value) > -1) {
raw_found = true;
break;
}
}

if (!raw_found) {
token.stack.push({
type: Twig.expression.type.filter,
value: "escape",
match: ["|escape", "escape"]
});
}

return token;
}

// Namespace for template storage and retrieval
Twig.Templates = {
registry: {}
Expand Down Expand Up @@ -1907,9 +1942,11 @@ var Twig = (function (Twig) {
return token;
},
parse: function (token, context, chain) {
var output = '';
var output = '',
// Parse the expression
result = Twig.expression.parse.apply(this, [token.stack, context]);

if (chain && Twig.expression.parse.apply(this, [token.stack, context]) === true) {
if (chain && result) {
chain = false;
// parse if output
output = Twig.parse.apply(this, [token.output, context]);
Expand Down Expand Up @@ -4939,6 +4976,7 @@ var Twig = (function (Twig) {
template = '';
}
return new Twig.Template({
options: this.options,
data: template
});
}
Expand Down Expand Up @@ -5047,6 +5085,8 @@ var Twig = (function (Twig) {
var id = params.id,
options = {
strict_variables: params.strict_variables || false,
// TODO: turn autoscape on in the next major version
autoescape: params.autoescape != null && params.autoescape || false,
allowInlineIncludes: params.allowInlineIncludes || false,
rethrow: params.rethrow || false
};
Expand Down
35 changes: 35 additions & 0 deletions src/twig.core.js
Expand Up @@ -480,6 +480,7 @@ var Twig = (function (Twig) {

case Twig.token.type.output:
Twig.expression.compile.apply(this, [token]);
Twig.autoescape.apply(this, [token]);
if (stack.length > 0) {
intermediate_output.push(token);
} else {
Expand Down Expand Up @@ -605,6 +606,40 @@ var Twig = (function (Twig) {
return tokens;
};

/**
* Autoescape the output token if needed
*
* @param {Object} data The output token.
*
* @return {Object} The modified token.
*/
Twig.autoescape = function(token) {
if (!this.options.autoescape) {
return token;
}

var raw_found = false;
var current_token;
for (var i=0, l=token.stack.length; i<l; i++) {
current_token = token.stack[i];
if (current_token.type === Twig.expression.type.filter
&& ["raw", "escape", "e"].indexOf(current_token.value) > -1) {
raw_found = true;
break;
}
}

if (!raw_found) {
token.stack.push({
type: Twig.expression.type.filter,
value: "escape",
match: ["|escape", "escape"]
});
}

return token;
}

// Namespace for template storage and retrieval
Twig.Templates = {
registry: {}
Expand Down
2 changes: 2 additions & 0 deletions src/twig.exports.js
Expand Up @@ -25,6 +25,8 @@ var Twig = (function (Twig) {
var id = params.id,
options = {
strict_variables: params.strict_variables || false,
// TODO: turn autoscape on in the next major version
autoescape: params.autoescape != null && params.autoescape || false,
allowInlineIncludes: params.allowInlineIncludes || false,
rethrow: params.rethrow || false
};
Expand Down
1 change: 1 addition & 0 deletions src/twig.functions.js
Expand Up @@ -175,6 +175,7 @@ var Twig = (function (Twig) {
template = '';
}
return new Twig.Template({
options: this.options,
data: template
});
}
Expand Down
9 changes: 9 additions & 0 deletions test/test.core.js
Expand Up @@ -259,6 +259,15 @@ describe("Twig.js Core ->", function() {
twig({data: '{% set _context = "test" %}{{ _context|json_encode }}'}).render().should.equal('{"_context":"test"}');
twig({data: '{% set _context = "test" %}{{ _context._context }}'}).render().should.equal("test");
});

it("should support autoescape option", function() {
twig({
autoescape: true,
data: '{{ value }}'
}).render({
value: "<test>&</test>"
}).should.equal('&lt;test&gt;&amp;&lt;/test&gt;');
});
});
});

41 changes: 41 additions & 0 deletions test/test.filters.js
Expand Up @@ -293,6 +293,15 @@ describe("Twig.js Filters ->", function() {
var test_template = twig({data: '{{ undef|escape }}' });
test_template.render().should.equal("" );
});

it("should not escape twice if autoescape is on", function() {
twig({
autoescape: true,
data: '{{ value }}'
}).render({
value: "<test>&</test>"
}).should.equal('&lt;test&gt;&amp;&lt;/test&gt;');
});
});

describe("e ->", function() {
Expand All @@ -305,6 +314,16 @@ describe("Twig.js Filters ->", function() {
var test_template = twig({data: '{{ undef|e }}' });
test_template.render().should.equal("" );
});

it("should not escape twice if autoescape is on", function() {
var template = twig({
autoescape: true,
data: '{{ value }}'
});
template.render({
value: "<test>&</test>"
}).should.equal('&lt;test&gt;&amp;&lt;/test&gt;');
});
});

describe("nl2br ->", function() {
Expand Down Expand Up @@ -503,6 +522,28 @@ describe("Twig.js Filters ->", function() {
});
});

describe('raw ->', function () {
it('should output the raw value if autoescape is on', function () {
var template = twig({
autoescape: true,
data: '{{ value|raw }}'
});
template.render({
value: "<test>&</test>"
}).should.equal('<test>&</test>');
});

it('should output the raw value if autoescape is off', function () {
var template = twig({
autoescape: false,
data: '{{ value|raw }}'
});
template.render({
value: "<test>&</test>"
}).should.equal('<test>&</test>');
});
});

describe('round ->', function () {
it('should round up (common)', function () {
var test_template = twig({data: "{{ 2.7|round }}"});
Expand Down
44 changes: 42 additions & 2 deletions twig.js
Expand Up @@ -494,6 +494,7 @@ var Twig = (function (Twig) {

case Twig.token.type.output:
Twig.expression.compile.apply(this, [token]);
Twig.autoescape.apply(this, [token]);
if (stack.length > 0) {
intermediate_output.push(token);
} else {
Expand Down Expand Up @@ -619,6 +620,40 @@ var Twig = (function (Twig) {
return tokens;
};

/**
* Autoescape the output token if needed
*
* @param {Object} data The output token.
*
* @return {Object} The modified token.
*/
Twig.autoescape = function(token) {
if (!this.options.autoescape) {
return token;
}

var raw_found = false;
var current_token;
for (var i=0, l=token.stack.length; i<l; i++) {
current_token = token.stack[i];
if (current_token.type === Twig.expression.type.filter
&& ["raw", "escape", "e"].indexOf(current_token.value) > -1) {
raw_found = true;
break;
}
}

if (!raw_found) {
token.stack.push({
type: Twig.expression.type.filter,
value: "escape",
match: ["|escape", "escape"]
});
}

return token;
}

// Namespace for template storage and retrieval
Twig.Templates = {
registry: {}
Expand Down Expand Up @@ -1907,9 +1942,11 @@ var Twig = (function (Twig) {
return token;
},
parse: function (token, context, chain) {
var output = '';
var output = '',
// Parse the expression
result = Twig.expression.parse.apply(this, [token.stack, context]);

if (chain && Twig.expression.parse.apply(this, [token.stack, context]) === true) {
if (chain && result) {
chain = false;
// parse if output
output = Twig.parse.apply(this, [token.output, context]);
Expand Down Expand Up @@ -4939,6 +4976,7 @@ var Twig = (function (Twig) {
template = '';
}
return new Twig.Template({
options: this.options,
data: template
});
}
Expand Down Expand Up @@ -5047,6 +5085,8 @@ var Twig = (function (Twig) {
var id = params.id,
options = {
strict_variables: params.strict_variables || false,
// TODO: turn autoscape on in the next major version
autoescape: params.autoescape != null && params.autoescape || false,
allowInlineIncludes: params.allowInlineIncludes || false,
rethrow: params.rethrow || false
};
Expand Down
6 changes: 3 additions & 3 deletions twig.min.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion twig.min.js.map

Large diffs are not rendered by default.