mirror of
https://github.com/zhigang1992/angular.js.git
synced 2026-04-24 03:55:49 +08:00
feat($interpolate): escaped interpolation expressions
This CL enables interpolation expressions to be escaped, by prefixing each character of their
start/end markers with a REVERSE SOLIDUS U+005C, and to render the escaped expression as a
regular interpolation expression.
Example:
`<span ng-init="foo='Hello'">{{foo}}, \\{\\{World!\\}\\}</span>` would be rendered as:
`<span ng-init="foo='Hello'">Hello, {{World!}}</span>`
This will also work with custom interpolation markers, for example:
module.
config(function($interpolateProvider) {
$interpolateProvider.startSymbol('\\\\');
$interpolateProvider.endSymbol('//');
}).
run(function($interpolate) {
// Will alert with "hello\\bar//":
alert($interpolate('\\\\foo//\\\\\\\\bar\\/\\/')({foo: "hello", bar: "world"}));
});
This change effectively only changes the rendering of these escaped markers, because they are
not context-aware, and are incapable of preventing nested expressions within those escaped
markers from being evaluated.
Therefore, backends are encouraged to ensure that when escaping expressions for security
reasons, every single instance of a start or end marker have each of its characters prefixed
with a backslash (REVERSE SOLIDUS, U+005C)
Closes #5601
Closes #7517
This commit is contained in:
@@ -61,6 +61,66 @@ describe('$interpolate', function() {
|
||||
}));
|
||||
|
||||
|
||||
describe('interpolation escaping', function() {
|
||||
var obj;
|
||||
beforeEach(function() {
|
||||
obj = {foo: 'Hello', bar: 'World'};
|
||||
});
|
||||
|
||||
|
||||
it('should support escaping interpolation signs', inject(function($interpolate) {
|
||||
expect($interpolate('{{foo}} \\{\\{bar\\}\\}')(obj)).toBe('Hello {{bar}}');
|
||||
expect($interpolate('\\{\\{foo\\}\\} {{bar}}')(obj)).toBe('{{foo}} World');
|
||||
}));
|
||||
|
||||
|
||||
it('should unescape multiple expressions', inject(function($interpolate) {
|
||||
expect($interpolate('\\{\\{foo\\}\\}\\{\\{bar\\}\\} {{foo}}')(obj)).toBe('{{foo}}{{bar}} Hello');
|
||||
expect($interpolate('{{foo}}\\{\\{foo\\}\\}\\{\\{bar\\}\\}')(obj)).toBe('Hello{{foo}}{{bar}}');
|
||||
expect($interpolate('\\{\\{foo\\}\\}{{foo}}\\{\\{bar\\}\\}')(obj)).toBe('{{foo}}Hello{{bar}}');
|
||||
expect($interpolate('{{foo}}\\{\\{foo\\}\\}{{bar}}\\{\\{bar\\}\\}{{foo}}')(obj)).toBe('Hello{{foo}}World{{bar}}Hello');
|
||||
}));
|
||||
|
||||
|
||||
it('should support escaping custom interpolation start/end symbols', function() {
|
||||
module(function($interpolateProvider) {
|
||||
$interpolateProvider.startSymbol('[[');
|
||||
$interpolateProvider.endSymbol(']]');
|
||||
});
|
||||
inject(function($interpolate) {
|
||||
expect($interpolate('[[foo]] \\[\\[bar\\]\\]')(obj)).toBe('Hello [[bar]]');
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
it('should unescape incomplete escaped expressions', inject(function($interpolate) {
|
||||
expect($interpolate('\\{\\{foo{{foo}}')(obj)).toBe('{{fooHello');
|
||||
expect($interpolate('\\}\\}foo{{foo}}')(obj)).toBe('}}fooHello');
|
||||
expect($interpolate('foo{{foo}}\\{\\{')(obj)).toBe('fooHello{{');
|
||||
expect($interpolate('foo{{foo}}\\}\\}')(obj)).toBe('fooHello}}');
|
||||
}));
|
||||
|
||||
|
||||
it('should not unescape markers within expressions', inject(function($interpolate) {
|
||||
expect($interpolate('{{"\\\\{\\\\{Hello, world!\\\\}\\\\}"}}')(obj)).toBe('\\{\\{Hello, world!\\}\\}');
|
||||
expect($interpolate('{{"\\{\\{Hello, world!\\}\\}"}}')(obj)).toBe('{{Hello, world!}}');
|
||||
expect(function() {
|
||||
$interpolate('{{\\{\\{foo\\}\\}}}')(obj);
|
||||
}).toThrowMinErr('$parse', 'lexerr',
|
||||
'Lexer Error: Unexpected next character at columns 0-0 [\\] in expression [\\{\\{foo\\}\\]');
|
||||
}));
|
||||
|
||||
|
||||
// This test demonstrates that the web-server is responsible for escaping every single instance
|
||||
// of interpolation start/end markers in an expression which they do not wish to evaluate,
|
||||
// because AngularJS will not protect them from being evaluated (due to the added complexity
|
||||
// and maintenance burden of context-sensitive escaping)
|
||||
it('should evaluate expressions between escaped start/end symbols', inject(function($interpolate) {
|
||||
expect($interpolate('\\{\\{Hello, {{bar}}!\\}\\}')(obj)).toBe('{{Hello, World!}}');
|
||||
}));
|
||||
});
|
||||
|
||||
|
||||
describe('interpolating in a trusted context', function() {
|
||||
var sce;
|
||||
beforeEach(function() {
|
||||
|
||||
Reference in New Issue
Block a user