mirror of
https://github.com/Hopiu/angular.js.git
synced 2026-03-17 07:40:22 +00:00
Ref: https://github.com/angular/angular.js/pull/4045 I have this sinking feeling that support this use case sort of encourages binding to function that blindly trust some html. For now, I'm fixing the issue while I think about the use cases some more. In the case of a function that performs any non-trivial work before wrapping the value (e.g. the showdown filter in issue #3980, or the binding to a simply wrapper function in issue #3932 if it did anything meaty), this fix makes it "work" - but performance is going to suck - you should bind to some other thing on scope that watches the actual source and adjusts itself when that changes (e.g. the showdown filter.) For the case of the wrapper in #3932, if one isn't performing sanitization or some such thing - then you the developer has insight into why that value is safe in that particular context - and it should be available simply by name and not as a result of a function taking any arbitrary input to make auditing of security a little saner. Closes #3932, #3980
130 lines
4.8 KiB
JavaScript
130 lines
4.8 KiB
JavaScript
'use strict';
|
|
|
|
describe('ngBind*', function() {
|
|
var element;
|
|
|
|
|
|
afterEach(function() {
|
|
dealoc(element);
|
|
});
|
|
|
|
|
|
describe('ngBind', function() {
|
|
|
|
it('should set text', inject(function($rootScope, $compile) {
|
|
element = $compile('<div ng-bind="a"></div>')($rootScope);
|
|
expect(element.text()).toEqual('');
|
|
$rootScope.a = 'misko';
|
|
$rootScope.$digest();
|
|
expect(element.hasClass('ng-binding')).toEqual(true);
|
|
expect(element.text()).toEqual('misko');
|
|
}));
|
|
|
|
|
|
it('should set text to blank if undefined', inject(function($rootScope, $compile) {
|
|
element = $compile('<div ng-bind="a"></div>')($rootScope);
|
|
$rootScope.a = 'misko';
|
|
$rootScope.$digest();
|
|
expect(element.text()).toEqual('misko');
|
|
$rootScope.a = undefined;
|
|
$rootScope.$digest();
|
|
expect(element.text()).toEqual('');
|
|
$rootScope.a = null;
|
|
$rootScope.$digest();
|
|
expect(element.text()).toEqual('');
|
|
}));
|
|
|
|
|
|
it('should suppress rendering of falsy values', inject(function($rootScope, $compile) {
|
|
element = $compile('<div><span ng-bind="null"></span>' +
|
|
'<span ng-bind="undefined"></span>' +
|
|
'<span ng-bind="\'\'"></span>-' +
|
|
'<span ng-bind="0"></span>' +
|
|
'<span ng-bind="false"></span>' +
|
|
'</div>')($rootScope);
|
|
$rootScope.$digest();
|
|
expect(element.text()).toEqual('-0false');
|
|
}));
|
|
});
|
|
|
|
|
|
describe('ngBindTemplate', function() {
|
|
|
|
it('should ngBindTemplate', inject(function($rootScope, $compile) {
|
|
element = $compile('<div ng-bind-template="Hello {{name}}!"></div>')($rootScope);
|
|
$rootScope.name = 'Misko';
|
|
$rootScope.$digest();
|
|
expect(element.hasClass('ng-binding')).toEqual(true);
|
|
expect(element.text()).toEqual('Hello Misko!');
|
|
}));
|
|
|
|
|
|
it('should render object as JSON ignore $$', inject(function($rootScope, $compile) {
|
|
element = $compile('<pre>{{ {key:"value", $$key:"hide"} }}</pre>')($rootScope);
|
|
$rootScope.$digest();
|
|
expect(fromJson(element.text())).toEqual({key:'value'});
|
|
}));
|
|
});
|
|
|
|
|
|
describe('ngBindHtml', function() {
|
|
describe('SCE disabled', function() {
|
|
beforeEach(function() {
|
|
module(function($sceProvider) { $sceProvider.enabled(false); });
|
|
});
|
|
|
|
it('should set html', inject(function($rootScope, $compile) {
|
|
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
|
$rootScope.html = '<div onclick="">hello</div>';
|
|
$rootScope.$digest();
|
|
expect(angular.lowercase(element.html())).toEqual('<div onclick="">hello</div>');
|
|
}));
|
|
});
|
|
|
|
|
|
describe('SCE enabled', function() {
|
|
it('should NOT set html for untrusted values', inject(function($rootScope, $compile) {
|
|
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
|
$rootScope.html = '<div onclick="">hello</div>';
|
|
expect($rootScope.$digest).toThrow();
|
|
}));
|
|
|
|
it('should NOT set html for wrongly typed values', inject(function($rootScope, $compile, $sce) {
|
|
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
|
$rootScope.html = $sce.trustAsCss('<div onclick="">hello</div>');
|
|
expect($rootScope.$digest).toThrow();
|
|
}));
|
|
|
|
it('should set html for trusted values', inject(function($rootScope, $compile, $sce) {
|
|
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
|
$rootScope.html = $sce.trustAsHtml('<div onclick="">hello</div>');
|
|
$rootScope.$digest();
|
|
expect(angular.lowercase(element.html())).toEqual('<div onclick="">hello</div>');
|
|
}));
|
|
|
|
it('should watch the string value to avoid infinite recursion', inject(function($rootScope, $compile, $sce) {
|
|
// Ref: https://github.com/angular/angular.js/issues/3932
|
|
// If the binding is a function that creates a new value on every call via trustAs, we'll
|
|
// trigger an infinite digest if we don't take care of it.
|
|
element = $compile('<div ng-bind-html="getHtml()"></div>')($rootScope);
|
|
$rootScope.getHtml = function() {
|
|
return $sce.trustAsHtml('<div onclick="">hello</div>');
|
|
};
|
|
$rootScope.$digest();
|
|
expect(angular.lowercase(element.html())).toEqual('<div onclick="">hello</div>');
|
|
}));
|
|
|
|
describe('when $sanitize is available', function() {
|
|
beforeEach(function() { module('ngSanitize'); });
|
|
|
|
it('should sanitize untrusted html', inject(function($rootScope, $compile) {
|
|
element = $compile('<div ng-bind-html="html"></div>')($rootScope);
|
|
$rootScope.html = '<div onclick="">hello</div>';
|
|
$rootScope.$digest();
|
|
expect(angular.lowercase(element.html())).toEqual('<div>hello</div>');
|
|
}));
|
|
});
|
|
});
|
|
|
|
});
|
|
});
|